summaryrefslogtreecommitdiffstats
path: root/cobbler
diff options
context:
space:
mode:
Diffstat (limited to 'cobbler')
-rw-r--r--cobbler/api.py56
-rw-r--r--cobbler/modules/authn_configfile.py5
-rw-r--r--cobbler/modules/authn_kerberos.py81
-rw-r--r--cobbler/modules/authz_allowall.py2
-rw-r--r--cobbler/remote.py27
-rw-r--r--cobbler/settings.py1
6 files changed, 149 insertions, 23 deletions
diff --git a/cobbler/api.py b/cobbler/api.py
index e6ef88b..6343035 100644
--- a/cobbler/api.py
+++ b/cobbler/api.py
@@ -24,6 +24,11 @@ import action_status
import action_validate
import sub_process
import module_loader
+import logging
+
+ERROR = 100
+INFO = 10
+DEBUG = 5
class BootAPI:
@@ -37,10 +42,33 @@ class BootAPI:
self.__dict__ = self.__shared_state
if not BootAPI.has_loaded:
+
+
+ logger = logging.getLogger("cobbler.api")
+ logger.setLevel(logging.DEBUG)
+ ch = logging.FileHandler("/var/log/cobbler/cobbler.log")
+ ch.setLevel(logging.DEBUG)
+ formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
+ ch.setFormatter(formatter)
+ logger.addHandler(ch)
+
BootAPI.has_loaded = True
module_loader.load_modules()
self._config = config.Config(self)
self.deserialize()
+ self.logger = logger
+ self.logger.debug("API handle initialized")
+
+ self.authn = self.get_module_from_file(
+ "authentication",
+ "module",
+ "authn_configfile"
+ )
+ self.authz = self.get_module_from_file(
+ "authorization",
+ "module",
+ "authz_allowall"
+ )
def version(self):
"""
@@ -48,6 +76,7 @@ class BootAPI:
Currently checks the RPM DB, which is not perfect.
Will return "?" if not installed.
"""
+ self.logger.debug("cobbler version")
cmd = sub_process.Popen("/bin/rpm -q cobbler", stdout=sub_process.PIPE, shell=True)
result = cmd.communicate()[0].replace("cobbler-","")
if result.find("not installed") != -1:
@@ -55,7 +84,6 @@ class BootAPI:
tokens = result[:result.rfind("-")].split(".")
return int(tokens[0]) + 0.1 * int(tokens[1]) + 0.001 * int(tokens[2])
-
def clear(self):
"""
Forget about current list of profiles, distros, and systems
@@ -99,12 +127,14 @@ class BootAPI:
"""
Return a blank, unconfigured system, unattached to a collection
"""
+ self.logger.debug("new_system")
return self._config.new_system(is_subobject=is_subobject)
def new_distro(self,is_subobject=False):
"""
Create a blank, unconfigured distro, unattached to a collection.
"""
+ self.logger.debug("new_distro")
return self._config.new_distro(is_subobject=is_subobject)
@@ -112,12 +142,14 @@ class BootAPI:
"""
Create a blank, unconfigured profile, unattached to a collection
"""
+ self.logger.debug("new_profile")
return self._config.new_profile(is_subobject=is_subobject)
def new_repo(self,is_subobject=False):
"""
Create a blank, unconfigured repo, unattached to a collection
"""
+ self.logger.debug("new_repo")
return self._config.new_repo(is_subobject=is_subobject)
def auto_add_repos(self):
@@ -125,6 +157,7 @@ class BootAPI:
Import any repos this server knows about and mirror them.
Credit: Seth Vidal.
"""
+ self.logger.debug("auto_add_repos")
try:
import yum
except:
@@ -164,6 +197,7 @@ class BootAPI:
for human admins, who may, for instance, forget to properly set up
their TFTP servers for PXE, etc.
"""
+ self.logger.debug("check")
check = action_check.BootCheck(self._config)
return check.run()
@@ -176,6 +210,7 @@ class BootAPI:
is not available on all platforms and can not detect "future"
kickstart format correctness.
"""
+ self.logger.debug("validateks")
validator = action_validate.Validate(self._config)
return validator.run()
@@ -186,6 +221,7 @@ class BootAPI:
/tftpboot. Any operations done in the API that have not been
saved with serialize() will NOT be synchronized with this command.
"""
+ self.logger.debug("sync")
sync = action_sync.BootSync(self._config)
return sync.run()
@@ -194,10 +230,12 @@ class BootAPI:
Take the contents of /var/lib/cobbler/repos and update them --
or create the initial copy if no contents exist yet.
"""
+ self.logger.debug("reposync")
reposync = action_reposync.RepoSync(self._config)
return reposync.run(name)
def status(self,mode):
+ self.logger.debug("status")
statusifier = action_status.BootStatusReport(self._config, mode)
return statusifier.run()
@@ -252,4 +290,20 @@ class BootAPI:
"""
return module_loader.get_modules_in_category(category)
+ def authenticate(self,user,password):
+ """
+ (Remote) access control.
+ """
+ self.logger.debug("authorize(%s)" % (user))
+ rc = self.authn.authenticate(self,user,password)
+ self.logger.debug("authorize(%s)=%s" % (user,rc))
+ return rc
+
+ def authorize(self,user,resource,arg1=None,arg2=None):
+ """
+ (Remote) access control.
+ """
+ rc = self.authz.authorize(self,user,resource,arg1,arg2)
+ self.logger.debug("authorize(%s,%s)=%s" % (user,resource,rc))
+ return rc
diff --git a/cobbler/modules/authn_configfile.py b/cobbler/modules/authn_configfile.py
index 5740efa..30637b7 100644
--- a/cobbler/modules/authn_configfile.py
+++ b/cobbler/modules/authn_configfile.py
@@ -52,7 +52,7 @@ def __parse_storage():
pass
return results
-def authenticate(username,password):
+def authenticate(api_handle,username,password):
"""
Validate a username/password combo, returning True/False
@@ -70,7 +70,4 @@ def authenticate(username,password):
return False
-if __name__ == "__main__":
- print authenticate("cobbler","cobbler")
- print authenticate("cobbler","bogus")
diff --git a/cobbler/modules/authn_kerberos.py b/cobbler/modules/authn_kerberos.py
new file mode 100644
index 0000000..7f85db6
--- /dev/null
+++ b/cobbler/modules/authn_kerberos.py
@@ -0,0 +1,81 @@
+"""
+Authentication module that uses kerberos.
+
+Copyright 2007, Red Hat, Inc
+Michael DeHaan <mdehaan@redhat.com>
+
+This software may be freely redistributed under the terms of the GNU
+general public license.
+
+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., 675 Mass Ave, Cambridge, MA 02139, USA.
+"""
+
+# NOTE: this is not using 'straight up' kerberos in that we
+# relay passwords through cobblerd for authentication, that may
+# be done later. It does of course check against kerberos,
+# however.
+
+# ALSO NOTE: we're calling out to a Perl program to make
+# this work. You must install Authen::Simple::Kerberos
+# from CPAN and the Kerberos libraries for this to work.
+# See the Cobbler Wiki for more info.
+
+# ALSO ALSO NOTE: set kerberos_realm in /var/lib/cobbler/settings
+# to something appropriate or this will never work. CASING
+# MATTERS. example.com != EXAMPLE.COM.
+
+import distutils.sysconfig
+import ConfigParser
+import sys
+import os
+from rhpl.translate import _, N_, textdomain, utf8
+import md5
+import traceback
+# since sub_process isn't available on older OS's
+try:
+ import sub_process as subprocess
+except:
+ import subprocess
+
+plib = distutils.sysconfig.get_python_lib()
+mod_path="%s/cobbler" % plib
+sys.path.insert(0, mod_path)
+
+import cexceptions
+import utils
+
+def register():
+ """
+ The mandatory cobbler module registration hook.
+ """
+ return "authn"
+
+def authenticate(api_handle,username,password):
+ """
+ Validate a username/password combo, returning True/False
+ Uses cobbler_auth_helper
+ """
+
+ realm = self.api.settings().kerberos_realm
+ api_handle.logger.debug("authenticating %s against %s" % (username,realm))
+
+ rc = subprocess.call([
+ "/usr/bin/cobbler_auth_help",
+ "--method=kerberos",
+ "--username=%s" % username,
+ "--password=%s" % password,
+ "--realm=%s" % realm
+ ])
+ print rc
+ if rc == 42:
+ api_handle.logger.debug("authenticated ok")
+ # authentication ok (FIXME: log)
+ return True
+ else:
+ api_handle.logger.debug("authentication failed")
+ # authentication failed
+ return False
+
+
diff --git a/cobbler/modules/authz_allowall.py b/cobbler/modules/authz_allowall.py
index 4125ed6..1b05630 100644
--- a/cobbler/modules/authz_allowall.py
+++ b/cobbler/modules/authz_allowall.py
@@ -32,7 +32,7 @@ def register():
"""
return "authz"
-def authorize(user,resource,arg1=None,arg2=None):
+def authorize(api_handle,user,resource,arg1=None,arg2=None):
"""
Validate a user against a resource.
"""
diff --git a/cobbler/remote.py b/cobbler/remote.py
index 081f8c8..e84827a 100644
--- a/cobbler/remote.py
+++ b/cobbler/remote.py
@@ -20,7 +20,6 @@ import os
import SimpleXMLRPCServer
from rhpl.translate import _, N_, textdomain, utf8
import xmlrpclib
-import logging
import random
import base64
@@ -52,7 +51,7 @@ class CobblerXMLRPCInterface:
def __init__(self,api,logger):
self.api = api
- self.logger = logger
+ self.logger = self.api.logger
def __sorter(self,a,b):
return cmp(a["name"],b["name"])
@@ -365,17 +364,6 @@ class CobblerReadWriteXMLRPCInterface(CobblerXMLRPCInterface):
self.token_cache = {}
self.object_cache = {}
random.seed(time.time())
- self.authn = self.api.get_module_from_file(
- "authentication",
- "module",
- "authn_configfile"
- )
- self.authz = self.api.get_module_from_file(
- "authorization",
- "module",
- "authz_allowall"
- )
-
def __next_id(self,retry=0):
"""
@@ -435,7 +423,7 @@ class CobblerReadWriteXMLRPCInterface(CobblerXMLRPCInterface):
FIXME: currently looks for users in /etc/cobbler/auth.conf
Would be very nice to allow for PAM and/or just Kerberos.
"""
- return self.authn.authenticate(input_user,input_password)
+ return self.api.authenticate(input_user,input_password)
def __validate_token(self,token):
"""
@@ -457,6 +445,7 @@ class CobblerReadWriteXMLRPCInterface(CobblerXMLRPCInterface):
raise CX(_("invalid token: %s" % token))
def check_access(self,token,resource,arg1=None,arg2=None):
+ self.logger.debug("check_access(%s, %s)" % (token,resource))
validated = self.__validate_token(token)
return self.__authorize(token,resource,arg1,arg2)
@@ -473,17 +462,18 @@ class CobblerReadWriteXMLRPCInterface(CobblerXMLRPCInterface):
method calls. The token will time out after a set interval if not
used. Re-logging in permitted.
"""
+ self.logger.debug("login (%s)" % login_user)
if self.__validate_user(login_user,login_password):
token = self.__make_token(login_user)
- self.logger.info("login succeeded: %s" % login_user)
+ self.logger.debug("login succeeded: %s" % login_user)
return token
else:
- self.logger.info("login failed: %s" % login_user)
+ self.logger.debug("login failed: %s" % login_user)
raise CX(_("login failed: %s") % login_user)
def __authorize(self,token,resource,arg1=None,arg2=None):
user = self.__get_user_from_token(token)
- if self.authz.authorize(user,resource,arg1,arg2):
+ if self.api.authorize(user,resource,arg1,arg2):
return True
else:
raise CX(_("user does not have access to resource: %s") % resource)
@@ -492,6 +482,7 @@ class CobblerReadWriteXMLRPCInterface(CobblerXMLRPCInterface):
"""
Retires a token ahead of the timeout.
"""
+ self.logger.debug("logout(%s)" % token)
if self.token_cache.has_key(token):
del self.token_cache[token]
return True
@@ -501,6 +492,7 @@ class CobblerReadWriteXMLRPCInterface(CobblerXMLRPCInterface):
"""
This is a demo function that does not return anything useful.
"""
+ self.logger.debug("token_check(%s)" % token)
self.__validate_token(token)
return True
@@ -830,3 +822,4 @@ class CobblerReadWriteXMLRPCServer(SimpleXMLRPCServer.SimpleXMLRPCServer):
self.allow_reuse_address = True
SimpleXMLRPCServer.SimpleXMLRPCServer.__init__(self,args)
+
diff --git a/cobbler/settings.py b/cobbler/settings.py
index 8f9527d..c1fe232 100644
--- a/cobbler/settings.py
+++ b/cobbler/settings.py
@@ -34,6 +34,7 @@ DEFAULTS = {
"dnsmasq_bin" : "/usr/sbin/dnsmasq",
"dnsmasq_conf" : "/etc/dnsmasq.conf",
"httpd_bin" : "/usr/sbin/httpd",
+ "kerberos_realm" : "example.org",
"kernel_options" : {
"lang" : " ",
"text" : None,