Diff
9 commits, 21 files changed
+2350 -131

file modified
+1 -1
@@ -1,1 +1,1 @@

- 0.6.0

+ 0.6.1

file modified
+9
@@ -1,4 +1,5 @@

  %{!?python_sitearch: %global python_sitearch %(%{__python} -c "from distutils.sysconfig import get_python_lib; print get_python_lib(1)")}

+ %{!?python_sitelib: %global python_sitelib %(%{__python} -c "from distutils.sysconfig import get_python_lib; print get_python_lib()")}

  

  Name: @PACKAGE_NAME@

  Version: @PACKAGE_VERSION@
@@ -89,6 +90,8 @@

  # Copy default sssd.conf file

  mkdir -p $RPM_BUILD_ROOT/%{_sysconfdir}/sssd

  install -m600 server/examples/sssd.conf $RPM_BUILD_ROOT%{_sysconfdir}/sssd/sssd.conf

+ install -m400 server/config/etc/sssd.api.conf $RPM_BUILD_ROOT%{_sysconfdir}/sssd/sssd.api.conf

+ install -m400 server/config/etc/sssd.api.d/* $RPM_BUILD_ROOT%{_sysconfdir}/sssd/sssd.api.d/

  

  # Remove .la files created by libtool

  rm -f \
@@ -131,6 +134,9 @@

  %attr(750,root,root) %dir %{_var}/log/%{name}

  %dir %{_sysconfdir}/sssd

  %config(noreplace) %{_sysconfdir}/sssd/sssd.conf

+ %config %{_sysconfdir}/sssd/sssd.api.conf

+ %attr(700,root,root) %dir %{_sysconfdir}/sssd/sssd.api.d

+ %config %{_sysconfdir}/sssd/sssd.api.d/

  %{_mandir}/man5/sssd.conf.5*

  %{_mandir}/man5/sssd-krb5.5*

  %{_mandir}/man5/sssd-ldap.5*
@@ -145,6 +151,9 @@

  %{_datadir}/locale/*/LC_MESSAGES/sss_client.mo

  %{_datadir}/locale/*/LC_MESSAGES/sss_daemon.mo

  %{python_sitearch}/pysss.so

+ %{python_sitelib}/*.py*

+ %{?fedora:%{python_sitelib}/*.egg-info}

+ 

  

  %files client

  /%{_lib}/libnss_sss.so.2

file modified
+1 -1
@@ -7,7 +7,7 @@

  }

  

  SAVED_PWD=$PWD

- version=$(grep "^AC_INIT" configure.ac | grep -E -o \[[0-9.]+\] | tr -d [])

+ version=`head -n1 VERSION`

  tag=$(echo ${version} | tr "." "_")

  

  trap "cd $SAVED_PWD; rm -rf sssd-${version} sssd-${version}.tar" EXIT

file modified
+21
@@ -11,6 +11,7 @@

  krb5plugindir = @krb5pluginpath@

  endif

  sssdconfdir = $(sysconfdir)/sssd

+ sssdapiplugindir = $(sssdconfdir)/sssd.api.d

  dbusintrospectdir = $(datarootdir)/sssd/introspect

  dbuspolicydir = $(sysconfdir)/dbus-1/system.d

  localedir = @localedir@
@@ -100,6 +101,10 @@

      pysss.la

  endif

  

+ dist_noinst_SCRIPTS = \

+     config/setup.py \

+     config/SSSDConfig.py

+ 

  ###############################

  # Global compilation settings #

  ###############################
@@ -537,6 +542,14 @@

  dist_init_SCRIPTS = \

      sysv/sssd

  

+ dist_sssdconf_DATA = \

+     config/etc/sssd.api.conf

+ dist_sssdapiplugin_DATA = \

+     config/etc/sssd.api.d/sssd-krb5.conf \

+     config/etc/sssd.api.d/sssd-ldap.conf \

+     config/etc/sssd.api.d/sssd-local.conf \

+     config/etc/sssd.api.d/sssd-proxy.conf

+ 

  installsssddirs::

  	mkdir -p \

      $(DESTDIR)$(includedir) \
@@ -558,6 +571,14 @@

      $(DESTDIR)$(logpath)

  

  install-exec-hook: installsssddirs

+ 	if [ "$(DESTDIR)" = "" ]; then \

+ 		cd $(srcdir)/config; $(PYTHON) setup.py install; \

+ 	else \

+ 		cd $(srcdir)/config; $(PYTHON) setup.py install --root=$(DESTDIR); \

+ 	fi

+ 

+ clean-local:

+ 	cd $(srcdir)/config; $(PYTHON) setup.py clean --all

  

  CLEANFILES = *.X */*.X */*/*.X

  

@@ -0,0 +1,645 @@

+ '''

+ Created on Sep 18, 2009

+ 

+ @author: sgallagh

+ '''

+ 

+ import os

+ import exceptions

+ from ConfigParser import RawConfigParser, NoSectionError

+ 

+ # Exceptions

+ class SSSDConfigException(Exception): pass

+ class ParsingError(Exception): pass

+ class AlreadyInitializedError(SSSDConfigException): pass

+ class NotInitializedError(SSSDConfigException): pass

+ class NoOutputFileError(SSSDConfigException): pass

+ class NoServiceError(SSSDConfigException): pass

+ class NoSectionError(SSSDConfigException): pass

+ class NoOptionError(SSSDConfigException): pass

+ class ServiceNotRecognizedError(SSSDConfigException): pass

+ class ServiceAlreadyExists(SSSDConfigException): pass

+ class NoDomainError(SSSDConfigException): pass

+ class DomainNotRecognized(SSSDConfigException): pass

+ class NoSuchProviderError(SSSDConfigException): pass

+ class NoSuchProviderSubtypeError(SSSDConfigException): pass

+ class ProviderSubtypeInUse(SSSDConfigException): pass

+ 

+ class SSSDConfigSchema(RawConfigParser):

+     def __init__(self, schemafile, schemaplugindir):

+         #TODO: get these from a global setting

+         if not schemafile:

+             schemafile = '/etc/sssd/sssd.api.conf'

+         if not schemaplugindir:

+             schemaplugindir = '/etc/sssd/sssd.api.d'

+ 

+         RawConfigParser.__init__(self, None, dict)

+         try:

+             #Read the primary config file

+             fd = open(schemafile, 'r')

+             self.readfp(fd)

+             fd.close()

+             # Read in the provider files

+             for file in os.listdir(schemaplugindir):

+                 fd = open(schemaplugindir+ "/" + file)

+                 self.readfp(fd)

+                 fd.close()

+         except IOError:

+             raise

+         except:

+             raise ParsingError

+ 

+         # Set up lookup table for types

+         self.type_lookup = {

+             'bool' : bool,

+             'int'  : int,

+             'long' : long,

+             'float': float,

+             'str'  : str,

+             'list' : list,

+             'None' : None

+             }

+ 

+         # Lookup table for acceptable boolean values

+         self.bool_lookup = {

+             'false' : False,

+             'true'  : True,

+             }

+ 

+     def _striplist(self, l):

+         return([x.strip() for x in l])

+ 

+     def get_options(self, section):

+         if not self.has_section(section):

+             raise NoSectionError

+         options = self.options(section)

+ 

+         # Parse values

+         parsed_options = {}

+         for option in options:

+             unparsed_option = self.get(section, option)

+             split_option = self._striplist(unparsed_option.split(','))

+             optionlen = len(split_option)

+ 

+             primarytype = self.type_lookup[split_option[0]]

+             subtype = self.type_lookup[split_option[1]]

+ 

+             if optionlen == 2:

+                 # This option has no defaults

+                 parsed_options[option] = \

+                     (primarytype,

+                      subtype,

+                      None)

+             elif optionlen == 3:

+                 if type(split_option[2]) == primarytype:

+                     parsed_options[option] = \

+                         (primarytype,

+                          subtype,

+                          split_option[2])

+                 elif primarytype == list:

+                     if (type(split_option[2]) == subtype):

+                         parsed_options[option] = \

+                             (primarytype,

+                              subtype,

+                              [split_option[2]])

+                     else:

+                         try:

+                             parsed_options[option] = \

+                                 (primarytype,

+                                  subtype,

+                                  [subtype(split_option[2])])

+                         except ValueError:

+                             raise ParsingError

+                 else:

+                     try:

+                         parsed_options[option] = \

+                             (primarytype,

+                              subtype,

+                              primarytype(split_option[2]))

+                     except ValueError:

+                         raise ParsingError

+ 

+             elif optionlen > 3:

+                 if (primarytype != list):

+                     raise ParsingError

+                 fixed_options = []

+                 for x in split_option[2:]:

+                     if type(x) != subtype:

+                         try:

+                             fixed_options.extend([subtype(x)])

+                         except ValueError:

+                             raise ParsingError

+                     else:

+                         fixed_options.extend([x])

+                 parsed_options[option] = \

+                     (primarytype,

+                      subtype,

+                      fixed_options)

+             else:

+                 # Bad config file

+                 raise ParsingError

+ 

+         return parsed_options

+ 

+     def get_option(self, section, option):

+         if not self.has_section(section):

+             raise NoSectionError(section)

+         if not self.has_option(section, option):

+             raise NoOptionError("Section [%s] has no option [%s]" %

+                                 (section, option))

+ 

+         return self.get_options(section)[option]

+ 

+     def get_defaults(self, section):

+         if not self.has_section(section):

+             raise NoSectionError(section)

+ 

+         schema_options = self.get_options(section)

+         defaults = dict([(x,schema_options[x][2])

+                          for x in schema_options.keys()

+                          if schema_options[x][2] != None])

+ 

+         return defaults

+ 

+     def get_services(self):

+         service_list = [x for x in self.sections()

+                         if x != 'service' and

+                         not x.startswith('domain') and

+                         not x.startswith('provider')]

+         return service_list

+ 

+     def get_providers(self):

+         providers = {}

+         for section in self._sections:

+             splitsection = section.split('/')

+             if (splitsection[0] == 'provider'):

+                 if(len(splitsection) == 3):

+                     if not providers.has_key(splitsection[1]):

+                         providers[splitsection[1]] = []

+                     providers[splitsection[1]].extend([splitsection[2]])

+         for key in providers.keys():

+             providers[key] = tuple(providers[key])

+         return providers

+ 

+ class SSSDService:

+     '''

+     classdocs

+     '''

+ 

+     def __init__(self, servicename, apischema):

+         if not isinstance(apischema, SSSDConfigSchema) or type(servicename) != str:

+             raise TypeError

+ 

+         if not apischema.has_section(servicename):

+             raise ServiceNotRecognizedError(servicename)

+ 

+         self.name = servicename

+         self.schema = apischema

+ 

+         # Set up the service object with any known defaults

+         self.options = {}

+ 

+         # Set up default options for all services

+         self.options.update(self.schema.get_defaults('service'))

+ 

+         # Set up default options for this service

+         self.options.update(self.schema.get_defaults(self.name))

+ 

+     def get_name(self):

+         return self.name

+ 

+     def list_options(self):

+         options = {}

+ 

+         # Get the list of available options for all services

+         schema_options = self.schema.get_options('service')

+         options.update(schema_options)

+ 

+         schema_options = self.schema.get_options(self.name)

+         options.update(schema_options)

+ 

+         return options

+ 

+     def _striplist(self, l):

+         return([x.strip() for x in l])

+ 

+     def set_option(self, optionname, value):

+         if self.schema.has_option(self.name, optionname):

+             option_schema = self.schema.get_option(self.name, optionname)

+         elif self.schema.has_option('service', optionname):

+             option_schema = self.schema.get_option('service', optionname)

+         else:

+             raise NoOptionError('Section [%s] has no option [%s]' % (self.name, optionname))

+ 

+         if value == None:

+             self.remove_option(optionname)

+             return

+ 

+         # If we were expecting a list and didn't get one,

+         # Create a list with a single entry. If it's the

+         # wrong subtype, it will fail below

+         if option_schema[0] == list and type(value) != list:

+             if type(value) == str:

+                 value = self._striplist(value.split(','))

+             else:

+                 value = [value]

+ 

+         if type(value) != option_schema[0]:

+             # If it's possible to convert it, do so

+             try:

+                 value = option_schema[0](value)

+             except ValueError:

+                 raise TypeError('Expected %s for %s, received %s' %

+                             (option_schema[0], optionname, type(value)))

+ 

+         if type(value) == list:

+             # Iterate through the list an ensure that all members

+             # are of the appropriate subtype

+             try:

+                 value = [option_schema[1](x)

+                          for x in value]

+             except ValueError:

+                 raise TypeError('Expected %s' % option_schema[1])

+ 

+         self.options[optionname] = value

+ 

+     def get_option(self, optionname):

+         if optionname in self.options.keys():

+             return self.options[optionname]

+         raise NoOptionError(optionname)

+ 

+     def get_all_options(self):

+         return self.options

+ 

+     def remove_option(self, optionname):

+         if self.options.has_key(optionname):

+             del self.options[optionname]

+ 

+ class SSSDDomain:

+     def __init__(self, domainname, apischema):

+         if not isinstance(apischema, SSSDConfigSchema) or type(domainname) != str:

+             raise TypeError

+ 

+         self.name = domainname

+         self.schema = apischema

+         self.active = False

+         self.oldname = None

+         self.providers = []

+ 

+         # Set up the domain object with any known defaults

+         self.options = {}

+ 

+         # Set up default options for all domains

+         self.options.update(self.schema.get_defaults('provider'))

+         self.options.update(self.schema.get_defaults('domain'))

+ 

+     def get_name(self):

+         return self.name

+ 

+     def set_active(self, active):

+         self.active = bool(active)

+ 

+     def list_options(self):

+         options = {}

+         # Get the list of available options for all domains

+         options.update(self.schema.get_options('provider'))

+ 

+         options.update(self.schema.get_options('domain'))

+ 

+         # Candidate for future optimization: will update primary type

+         # for each subtype

+         for (provider, providertype) in self.providers:

+             schema_options = self.schema.get_options('provider/%s'

+                                                      % provider)

+             options.update(schema_options)

+             schema_options = self.schema.get_options('provider/%s/%s'

+                                                      % (provider, providertype))

+             options.update(schema_options)

+         return options

+ 

+     def list_provider_options(self, provider, provider_type=None):

+         #TODO section checking

+ 

+         options = self.schema.get_options('provider/%s' % provider)

+         if(provider_type):

+             options.update(self.schema.get_options('provider/%s/%s' %

+                                                    (provider, provider_type)))

+         else:

+             # Add options from all provider subtypes

+             known_providers = self.list_providers()

+             for provider_type in known_providers[provider]:

+                 options.update(self.list_provider_options(provider,

+                                                           provider_type))

+         return options

+ 

+     def list_providers(self):

+         return self.schema.get_providers()

+ 

+     def set_option(self, option, value):

+         options = self.list_options()

+         if (option not in options.keys()):

+             raise NoOptionError('Section [%s] has no option [%s]' %

+                                 (self.name, option))

+ 

+         if value == None:

+             self.remove_option(option)

+             return

+ 

+         option_schema = options[option]

+ 

+         # If we were expecting a list and didn't get one,

+         # Create a list with a single entry. If it's the

+         # wrong subtype, it will fail below

+         if option_schema[0] == list and type(value) != list:

+             if type(value) == str:

+                 value = self._striplist(value.split(','))

+             else:

+                 value = [value]

+ 

+         if type(value) != option_schema[0]:

+             # If it's possible to convert it, do so

+             try:

+                 value = option_schema[0](value)

+             except ValueError:

+                 raise TypeError('Expected %s for %s, received %s' %

+                             (option_schema[0], option, type(value)))

+ 

+         if type(value) == list:

+             # Iterate through the list an ensure that all members

+             # are of the appropriate subtype

+             try:

+                 value = [option_schema[1](x)

+                          for x in value]

+             except ValueError:

+                 raise TypeError('Expected %s' % option_schema[1])

+ 

+         # Check whether we're adding a provider entry.

+         # This requires special handling

+         is_provider = option.rfind('_provider')

+         if (is_provider > 0):

+             provider = option[:is_provider]

+             self.add_provider(value, provider)

+         else:

+             self.options[option] = value

+ 

+     def get_option(self, optionname):

+         if optionname in self.options.keys():

+             return self.options[optionname]

+         raise NoOptionError(optionname)

+ 

+     def get_all_options(self):

+         return self.options

+ 

+     def remove_option(self, optionname):

+         if optionname in self.options.keys():

+             del self.options[optionname]

+ 

+     def add_provider(self, provider, provider_type):

+         # Check that provider and provider_type are valid

+         configured_providers = self.list_providers()

+         if provider in configured_providers.keys():

+             if provider_type not in configured_providers[provider]:

+                 raise NoSuchProviderSubtypeError(provider_type)

+         else:

+             raise NoSuchProviderError

+ 

+         # Don't add a provider twice

+         with_this_type = [x for x in self.providers if x[1] == provider_type]

+         if len(with_this_type) > 1:

+             # This should never happen!

+             raise ProviderSubtypeInUser

+         if len(with_this_type) == 1:

+             if with_this_type[0][0] != provider:

+                 raise ProviderSubtypeInUse(with_this_type[0][0])

+         else:

+             self.providers.extend([(provider, provider_type)])

+ 

+         option_name = '%s_provider' % provider_type

+         self.options[option_name] = provider

+ 

+         # Add defaults for this provider

+         self.options.update(self.schema.get_defaults('provider/%s' %

+                                                      provider))

+         self.options.update(self.schema.get_defaults('provider/%s/%s' %

+                                                      (provider,

+                                                       provider_type)))

+ 

+ 

+     def remove_provider(self, provider, provider_type):

+         if (provider,provider_type) not in self.providers:

+             return

+ 

+         # TODO: safely remove any unused options when removing

+         # the provider. This will require modifying the schema

+         # to account for multiple providers making use of the

+         # same options (such ask krb5_realm)

+ 

+         self.providers.remove((provider,provider_type))

+ 

+ class SSSDConfig(RawConfigParser):

+     def __init__(self, schemafile=None, schemaplugindir=None):

+         RawConfigParser.__init__(self, None, dict)

+         self.schema = SSSDConfigSchema(schemafile, schemaplugindir)

+         self.configfile = None

+         self.initialized = False

+ 

+     def import_config(self,configfile=None):

+         if self.initialized:

+             raise AlreadyInitializedError

+ 

+         if not configfile:

+             #TODO: get this from a global setting

+             configfile = '/etc/sssd/sssd.conf'

+         # open will raise an IOError if it fails

+         fd = open(configfile, 'r')

+ 

+         try:

+             self.readfp(fd)

+         except:

+             raise ParsingError

+ 

+         fd.close()

+         self.configfile = configfile

+         self.initialized = True

+ 

+     def new_config(self):

+         if self.initialized:

+             raise AlreadyInitializedError

+ 

+         self.initialized = True

+ 

+         #Initialize all services

+         for servicename in self.schema.get_services():

+             service = self.new_service(servicename)

+ 

+     def write(self, outputfile=None):

+         if not self.initialized:

+             raise NotInitializedError

+ 

+         if outputfile == None:

+             if(self.configfile == None):

+                 raise NoOutputFileError

+ 

+             outputfile = self.configfile

+ 

+         # open() will raise IOError if it fails

+         of = open(outputfile, 'w')

+         RawConfigParser.write(self, of)

+         of.close()

+ 

+     def list_services(self):

+         if not self.initialized:

+             raise NotInitializedError

+ 

+         service_list = [x for x in self.sections()

+                         if not x.startswith('domain')]

+         return service_list

+ 

+     def get_service(self, name):

+         if not self.initialized:

+             raise NotInitializedError

+         if not self.has_section(name):

+             raise NoServiceError

+ 

+         service = SSSDService(name, self.schema)

+         [service.set_option(option, value)

+          for (option,value) in self.items(name)]

+ 

+         return service

+ 

+     def new_service(self, name):

+         if not self.initialized:

+             raise NotInitializedError

+         if (self.has_section(name)):

+             raise ServiceAlreadyExists(name)

+ 

+         service = SSSDService(name, self.schema)

+         self.save_service(service)

+         return service

+ 

+     def delete_service(self, name):

+         if not self.initialized:

+             raise NotInitializedError

+         self.remove_section(name)

+ 

+     def save_service(self, service):

+         if not self.initialized:

+             raise NotInitializedError

+         if not isinstance(service, SSSDService):

+             raise TypeError

+ 

+         name = service.get_name()

+         # Ensure that the existing section is removed

+         # This way we ensure that we are getting a

+         # complete copy of the service.

+         # remove_section() is a noop if the section

+         # does not exist.

+         self.remove_section(name)

+         self.add_section(name)

+         option_dict = service.get_all_options()

+         for option in option_dict.keys():

+             value = option_dict[option]

+             if (type(value) == list):

+                 value = ', '.join(value)

+ 

+             self.set(name, option, value)

+ 

+     def _striplist(self, l):

+         return([x.strip() for x in l])

+ 

+     def list_active_domains(self):

+         if not self.initialized:

+             raise NotInitializedError

+ 

+         if (self.has_option('sssd', 'domains')):

+             active_domains = self._striplist(self.get('sssd', 'domains').split(','))

+         else:

+             active_domains = []

+ 

+         domains = [x for x in self.list_domains()

+                    if x in active_domains]

+         return domains

+ 

+     def list_inactive_domains(self):

+         if not self.initialized:

+             raise NotInitializedError

+ 

+         if (self.has_option('sssd', 'domains')):

+             active_domains = self._striplist(self.get('sssd', 'domains').split(','))

+         else:

+             active_domains = []

+ 

+         domains = [x for x in self.list_domains()

+                    if x not in active_domains]

+         return domains

+ 

+     def list_domains(self):

+         if not self.initialized:

+             raise NotInitializedError

+         domains = [x[7:] for x in self.sections() if x.startswith('domain/')]

+         return domains

+ 

+     def get_domain(self, name):

+         if not self.initialized:

+             raise NotInitializedError

+         if not self.has_section('domain/%s' % name):

+             raise NoDomainError(name)

+ 

+         domain = SSSDDomain(name, self.schema)

+ 

+         # Read in the providers first or we may have type

+         # errors trying to read in their options

+         providers = [x for x in self.items('domain/%s' % name)

+                      if x[0].rfind('_provider') > 0]

+         [domain.set_option(option, value)

+          for (option, value) in providers]

+ 

+         [domain.set_option(option, value)

+          for (option,value) in self.items('domain/%s' % name)

+          if (option,value) not in providers]

+ 

+         return domain

+ 

+     def new_domain(self, name):

+         if not self.initialized:

+             raise NotInitializedError

+         if self.has_section('domain/%s' % name):

+             raise DomainAlreadyExistsError

+ 

+         domain = SSSDDomain(name, self.schema)

+         self.save_domain(domain);

+         return domain

+ 

+     def delete_domain(self, name):

+         if not self.initialized:

+             raise NotInitializedError

+         self.remove_section('domain/%s' % name)

+ 

+     def save_domain(self, domain):

+         if not self.initialized:

+             raise NotInitializedError

+         if not isinstance(domain, SSSDDomain):

+             raise TypeError

+ 

+         name = domain.get_name()

+         sectionname = 'domain/%s' % name

+         # Ensure that the existing section is removed

+         # This way we ensure that we are getting a

+         # complete copy of the service.

+         # remove_section() is a noop if the section

+         # does not exist.

+         self.remove_section(sectionname)

+         self.add_section(sectionname)

+         option_dict = domain.get_all_options()

+         [self.set(sectionname, option, option_dict[option])

+          for option in option_dict.keys()]

+ 

+         if domain.active:

+             if domain.get_name not in self.list_active_domains():

+                 # Add it to the list of active domains

+                 if (self.has_option('sssd','domains')):

+                     active_domains = self.get('sssd', 'domains')

+                     active_domains += ", %s" % domain.get_name()

+                 else:

+                     active_domains = domain.get_name()

+                 self.set('sssd', 'domains', active_domains)

The added file is too large to be shown here, see it at: server/config/SSSDConfigTest.py
@@ -0,0 +1,48 @@

+ # Format:

+ # option = type, subtype[, default]

+ 

+ [service]

+ # Options available to all services

+ debug_level = int, None, 0

+ command = str, None

+ reconnection_retries = int, None, 3

+ 

+ [sssd]

+ # Monitor service

+ config_file_version = int, None, 2

+ services = list, str, nss, pam

+ domains = list, str

+ sbus_timeout = int, None, -1

+ re_expression = str, None, (?P<name>[^@]+)@?(?P<domain>[^@]*$)

+ full_name_format = str, None, %1$s@%2$s

+ 

+ [nss]

+ # Name service

+ nss_enum_cache_timeout = int, None

+ nss_entry_cache_timeout = int, None

+ nss_entry_cache_no_wait_timeout = int, None

+ nss_entry_negative_timeout = int, None

+ nss_filter_users = list, str, root

+ nss_filter_groups = list, str, root

+ nss_filter_users_in_groups = bool, None, true

+ 

+ [pam]

+ # Authentication service

+ 

+ [provider]

+ #Available provider types

+ id_provider = str, None

+ auth_provider = str, None

+ access_provider = str, None

+ chpass_provider = str, None

+ 

+ [domain]

+ # Options available to all domains

+ debug_level = int, None, 0

+ min_id = int, None, 1000

+ max_id = int, None

+ timeout = int, None, 0

+ magic_private_groups = bool, None, false

+ enumerate = bool, None, true

+ cache_credentials = bool, None, false

+ use_fully_qualified_names = bool, None, false

@@ -0,0 +1,13 @@

+ [provider/krb5]

+ krb5_kdcip = str, None

+ krb5_realm = str, None

+ krb5_auth_timeout = int, None

+ 

+ [provider/krb5/auth]

+ krb5_ccachedir = str, None

+ krb5_ccname_template = str, None

+ 

+ [provider/krb5/access]

+ 

+ [provider/krb5/chpass]

+ krb5_changepw_principal = str, None 

\ No newline at end of file

@@ -0,0 +1,32 @@

+ [provider/ldap]

+ ldap_uri = str, None, ldap://localhost

+ ldap_schema = str, None, rfc2307

+ ldap_default_bind_dn = str, None

+ ldap_default_authtok_type = str, None

+ ldap_default_authtok = str, None

+ ldap_network_timeout = int, None

+ ldap_opt_timeout = int, None

+ ldap_tls_reqcert = str, None

+ 

+ [provider/ldap/id]

+ ldap_user_search_base = str, None

+ ldap_user_object_class = str, None

+ ldap_user_name = str, None

+ ldap_user_uid_number = str, None

+ ldap_user_gid_number = str, None

+ ldap_user_gecos = str, None

+ ldap_user_homedir = str, None

+ ldap_user_shell = str, None

+ ldap_user_uuid = str, None

+ ldap_user_principal = str, None

+ ldap_user_fullname = str, None

+ ldap_user_memberof = str, None

+ ldap_group_search_base = str, None

+ ldap_group_object_class = str, None

+ ldap_group_name = str, None

+ ldap_group_gid_number = str, None

+ ldap_group_member = str, None

+ ldap_group_UUID = str, None

+ ldap_force_upper_case_realm = bool, None

+ 

+ [provider/ldap/auth]

@@ -0,0 +1,11 @@

+ [provider/local]

+ 

+ [provider/local/id]

+ default_shell = str, None, /bin/bash

+ base_directory = str, None, /home

+ 

+ [provider/local/auth]

+ 

+ [provider/local/access]

+ 

+ [provider/local/chpass] 

\ No newline at end of file

@@ -0,0 +1,7 @@

+ [provider/proxy]

+ 

+ [provider/proxy/id]

+ proxy_lib_name = str, None

+ 

+ [provider/proxy/auth]

+ proxy_pam_target = str, None

@@ -0,0 +1,34 @@

+ # Authors:

+ #  Stephen Gallagher <sgallagh@redhat.com>

+ #

+ # Copyright (C) 2009  Red Hat

+ # see file 'COPYING' for use and warranty information

+ #

+ # 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; version 2 only

+ #

+ # 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

+ 

+ """

+ Python-level packaging using distutils.

+ """

+ 

+ from distutils.core import setup

+ 

+ setup(

+     name='SSSDConfig',

+     version='1',

+     license='GPLv3+',

+     url='http://fedorahosted.org/sssd',

+     py_modules=[

+     'SSSDConfig',

+     ],

+ )

@@ -0,0 +1,7 @@

+ # Format:

+ # option = type, subtype[, default]

+ 

+ [service]

+ # Options available to all services

+ debug_level = int, None, 0

+ command 

\ No newline at end of file

@@ -0,0 +1,3 @@

+ [sssd]

+ services

+ config_file_version = 2

@@ -0,0 +1,42 @@

+ [nss]

+ nss_filter_groups = root

+ nss_entry_negative_timeout = 15

+ debug_level = 0

+ nss_filter_users_in_groups = true

+ nss_filter_users = root

+ nss_entry_cache_no_wait_timeout = 60

+ nss_entry_cache_timeout = 600

+ nss_enum_cache_timeout = 120

+ 

+ [sssd]

+ services = nss, pam

+ reconnection_retries = 3

+ domains = LOCAL, IPA

+ config_file_version = 2

+ 

+ [domain/PROXY]

+ id_provider = proxy

+ auth_provider = proxy

+ debug_level = 0

+ 

+ [domain/IPA]

+ id_provider = ldap

+ auth_provider = krb5

+ debug_level = 0

+ 

+ [domain/LOCAL]

+ id_provider = local

+ auth_provider = local

+ debug_level = 0

+ 

+ [domain/LDAP]

+ id_provider = ldap

+ auth_provider = ldap

+ debug_level = 0

+ 

+ [pam]

+ debug_level = 0

+ 

+ [dp]

+ debug_level = 0

+ 

file modified
+26 -73
@@ -6,7 +6,7 @@

  "Project-Id-Version: pl\n"

  "Report-Msgid-Bugs-To: sssd-devel@lists.fedorahosted.org\n"

  "POT-Creation-Date: 2009-09-25 13:56-0400\n"

- "PO-Revision-Date: 2009-09-16 17:20+0200\n"

+ "PO-Revision-Date: 2009-09-26 12:28+0200\n"

  "Last-Translator: Piotr Drąg <piotrdrag@gmail.com>\n"

  "Language-Team: Polish <fedora-trans-pl@redhat.com>\n"

  "MIME-Version: 1.0\n"
@@ -25,7 +25,7 @@

  

  #: tools/sss_groupdel.c:109

  msgid "Specify group to delete\n"

- msgstr "Podaj grupę do usunięcia\n"

+ msgstr "Proszę podać grupę do usunięcia\n"

  

  #: tools/sss_groupdel.c:119 tools/sss_groupmod.c:145 tools/sss_userdel.c:119

  #: tools/sss_useradd.c:216 tools/sss_groupadd.c:121 tools/sss_usermod.c:160
@@ -35,21 +35,19 @@

  #: tools/sss_groupdel.c:127 tools/sss_groupmod.c:152 tools/sss_userdel.c:127

  #: tools/sss_useradd.c:224 tools/sss_groupadd.c:129 tools/sss_usermod.c:168

  msgid "Invalid domain specified in FQDN\n"

- msgstr ""

+ msgstr "Podano nieprawidłową domenę w FQDN\n"

  

  #: tools/sss_groupdel.c:140 tools/sss_groupmod.c:192 tools/sss_groupadd.c:138

- #, fuzzy

  msgid "The selected GID is outside the allowed range\n"

- msgstr "Wybrany GID jest spoza wszystkich zakresów domeny\n"

+ msgstr "Wybrany GID jest spoza dozwolonego zakresu\n"

  

  #: tools/sss_groupdel.c:149

  msgid "Transaction error. Could not remove group.\n"

  msgstr "Błąd transakcji. Nie można usunąć grupy.\n"

  

  #: tools/sss_groupdel.c:164

- #, fuzzy

  msgid "No such group\n"

- msgstr "Nie ma takiego użytkownika\n"

+ msgstr "Nie ma takiej grupy\n"

  

  #: tools/sss_groupdel.c:168

  msgid "Internal error. Could not remove group.\n"
@@ -69,17 +67,16 @@

  

  #: tools/sss_groupmod.c:133

  msgid "Specify group to modify\n"

- msgstr "Podaj grupę do zmodyfikowania\n"

+ msgstr "Proszę podać grupę do zmodyfikowania\n"

  

  #: tools/sss_groupmod.c:163 tools/sss_groupmod.c:179 tools/sss_useradd.c:233

  #: tools/sss_usermod.c:183 tools/sss_usermod.c:199

- #, fuzzy

  msgid "Internal error while parsing parameters\n"

- msgstr "Wewnętrzny błąd. Nie można usunąć użytkownika.\n"

+ msgstr "Wewnętrzny błąd podczas przetwarzania parametrów\n"

  

  #: tools/sss_groupmod.c:170 tools/sss_groupmod.c:186

  msgid "Member groups must be in the same domain as parent group\n"

- msgstr ""

+ msgstr "Członkowie grupy muszą być w tej samej domenie co grupa nadrzędna\n"

  

  #: tools/sss_groupmod.c:200 tools/sss_groupmod.c:223

  msgid "Transaction error. Could not modify group.\n"
@@ -88,22 +85,22 @@

  #: tools/sss_groupmod.c:215

  msgid "Could not modify group - check if member group names are correct\n"

  msgstr ""

- "Nie można zmodyfikować grupy - sprawdź, czy nazwy członków grupy są "

+ "Nie można zmodyfikować grupy - proszę sprawdzić, czy nazwy członków grupy są "

  "poprawne\n"

  

  #: tools/sss_groupmod.c:219

  msgid "Could not modify group - check if groupname is correct\n"

  msgstr ""

- "Nie można zmodyfikować grupy - sprawdź, czy nazwa grupy jest poprawna\n"

+ "Nie można zmodyfikować grupy - proszę sprawdzić, czy nazwa grupy jest "

+ "poprawna\n"

  

  #: tools/sss_userdel.c:109

  msgid "Specify user to delete\n"

- msgstr "Podaj użytkownika do usunięcia\n"

+ msgstr "Proszę podać użytkownika do usunięcia\n"

  

  #: tools/sss_userdel.c:139 tools/sss_useradd.c:270 tools/sss_usermod.c:174

- #, fuzzy

  msgid "The selected UID is outside the allowed range\n"

- msgstr "Wybrany UID jest spoza wszystkich zakresów domeny\n"

+ msgstr "Wybrany UID jest spoza dozwolonego zakresu\n"

  

  #: tools/sss_userdel.c:148

  msgid "Transaction error. Could not remove user.\n"
@@ -140,7 +137,7 @@

  

  #: tools/sss_useradd.c:161 tools/sss_usermod.c:85

  msgid "Home directory"

- msgstr "Folder domowy"

+ msgstr "Katalog domowy"

  

  #: tools/sss_useradd.c:162 tools/sss_usermod.c:86

  msgid "Login shell"
@@ -152,11 +149,11 @@

  

  #: tools/sss_useradd.c:206

  msgid "Specify user to add\n"

- msgstr "Podaj użytkownika do dodania\n"

+ msgstr "Proszę podać użytkownika do dodania\n"

  

  #: tools/sss_useradd.c:240 tools/sss_usermod.c:190 tools/sss_usermod.c:206

  msgid "Groups must be in the same domain as user\n"

- msgstr ""

+ msgstr "Grupy muszą być w tej samej domenie co użytkownik\n"

  

  #: tools/sss_useradd.c:249

  msgid "Cannot get group information for the user\n"
@@ -164,7 +161,7 @@

  

  #: tools/sss_useradd.c:263

  msgid "Cannot set default values\n"

- msgstr ""

+ msgstr "Nie można ustawić domyślnych wartości\n"

  

  #: tools/sss_useradd.c:279 tools/sss_usermod.c:221 tools/sss_usermod.c:243

  msgid "Transaction error. Could not modify user.\n"
@@ -180,16 +177,15 @@

  

  #: tools/sss_groupadd.c:111

  msgid "Specify group to add\n"

- msgstr "Podaj grupę do dodania\n"

+ msgstr "Proszę podać grupę do dodania\n"

  

  #: tools/sss_groupadd.c:147 tools/sss_groupadd.c:166

  msgid "Transaction error. Could not add group.\n"

  msgstr "Błąd transakcji. Nie można dodać grupy.\n"

  

  #: tools/sss_groupadd.c:161

- #, fuzzy

  msgid "A group with the same name or GID already exists\n"

- msgstr "Grupa o tej samej nazwie lub UID już istnieje\n"

+ msgstr "Grupa o tej samej nazwie lub GID już istnieje\n"

  

  #: tools/sss_usermod.c:83

  msgid "The GID of the user"
@@ -205,67 +201,24 @@

  

  #: tools/sss_usermod.c:89

  msgid "Lock the account"

- msgstr "Zablokuj konto"

+ msgstr "Zablokowanie konta"

  

  #: tools/sss_usermod.c:90

  msgid "Unlock the account"

- msgstr "Odblokuj konto"

+ msgstr "Odblokowanie konta"

  

  #: tools/sss_usermod.c:150

  msgid "Specify user to modify\n"

- msgstr "Podaj użytkownika do zmodyfikowania\n"

+ msgstr "Proszę podać użytkownika do zmodyfikowania\n"

  

  #: tools/sss_usermod.c:235

  msgid "Could not modify user - check if group names are correct\n"

  msgstr ""

- "Nie można zmodyfikować użytkownika - sprawdź, czy nazwy grup są poprawne\n"

+ "Nie można zmodyfikować użytkownika - proszę sprawdzić, czy nazwy grup są "

+ "poprawne\n"

  

  #: tools/sss_usermod.c:239

  msgid "Could not modify user - check if username is correct\n"

  msgstr ""

- "Nie można zmodyfikować użytkownika - sprawdź, czy nazwa użytkownika jest "

- "poprawna\n"

- 

- #~ msgid "Cannot get domain info\n"

- #~ msgstr "Nie można uzyskać informacji o domenie\n"

- 

- #~ msgid "Selected domain %s conflicts with selected GID %llu\n"

- #~ msgstr "Wybrana domena %s jest w konflikcie z wybranym GID %llu\n"

- 

- #~ msgid "Cannot delete group from domain using the legacy tools\n"

- #~ msgstr "Nie można usunąć grupy z domeny używając przestarzałych narzędzi\n"

- 

- #~ msgid "Unsupported domain type\n"

- #~ msgstr "Nieobsługiwany typ domeny\n"

- 

- #~ msgid "Error looking up domain\n"

- #~ msgstr "Błąd podczas wyszukiwania domeny\n"

- 

- #~ msgid "Group nesting is not supported in this domain\n"

- #~ msgstr "Zagnieżdżanie grupy nie jest obsługiwane w tej domenie\n"

- 

- #~ msgid "Changing gid only allowed inside the same domain\n"

- #~ msgstr "Zmienianie GOD jest dozwolone tylko w tej samej domenie\n"

- 

- #~ msgid "Selected domain %s conflicts with selected UID %llu\n"

- #~ msgstr "Wybrana domena %s jest w konflikcie z wybranym UID %llu\n"

- 

- #~ msgid "Cannot delete user from domain using the legacy tools\n"

- #~ msgstr ""

- #~ "Nie można usunąć użytkownika z domeny używając przestarzałych narzędzi\n"

- 

- #~ msgid "Cannot add user to domain using the legacy tools\n"

- #~ msgstr ""

- #~ "Nie można dodać użytkownika do domeny używając przestarzałych narzędzi\n"

- 

- #~ msgid "Out of memory.\n"

- #~ msgstr "Brak pamięci.\n"

- 

- #~ msgid "Cannot add group to domain using the legacy tools\n"

- #~ msgstr "Nie można dodać grupy do domeny używając przestarzałych narzędzi\n"

- 

- #~ msgid "Unsupported domain type"

- #~ msgstr "Nieobsługiwany typ domeny"

- 

- #~ msgid "Changing uid only allowed inside the same domain\n"

- #~ msgstr "Zmienianie UID jest dozwolone tylko w tej samej domenie\n"

+ "Nie można zmodyfikować użytkownika - proszę sprawdzić, czy nazwa użytkownika "

+ "jest poprawna\n"

file modified
+2 -2
@@ -36,8 +36,8 @@

      { "ldap_default_bind_dn", SDAP_STRING, NULL_STRING, NULL_STRING },

      { "ldap_default_authtok_type", SDAP_STRING, NULL_STRING, NULL_STRING},

      { "ldap_default_authtok", SDAP_BLOB, NULL_BLOB, NULL_BLOB },

-     { "ldap_network_timeout", SDAP_NUMBER, { .number = 5 }, NULL_NUMBER },

-     { "ldap_opt_timeout", SDAP_NUMBER, { .number = 5 }, NULL_NUMBER },

+     { "ldap_network_timeout", SDAP_NUMBER, { .number = 60 }, NULL_NUMBER },

+     { "ldap_opt_timeout", SDAP_NUMBER, { .number = 60 }, NULL_NUMBER },

      { "ldap_tls_reqcert", SDAP_STRING, { "hard" }, NULL_STRING },

      { "ldap_user_search_base", SDAP_STRING, { "ou=People,dc=example,dc=com" }, NULL_STRING },

      { "ldap_user_search_scope", SDAP_STRING, { "sub" }, NULL_STRING },

@@ -1530,7 +1530,10 @@

  

      /* FIXME: get timeouts from configuration, for now 10 minutes */

      ret = sdap_op_add(state, state->ev, state->sh, msgid,

-                       sdap_get_users_done, req, 600, &state->op);

+                       sdap_get_users_done, req,

+                       sdap_go_get_int(state->opts->basic,

+                                       SDAP_NETWORK_TIMEOUT),

+                       &state->op);

      if (ret) {

          DEBUG(1, ("Failed to set up operation!\n"));

          tevent_req_error(req, ret);
@@ -1754,7 +1757,10 @@

  

      /* FIXME: get timeouts from configuration, for now 10 minutes */

      ret = sdap_op_add(state, state->ev, state->sh, msgid,

-                       sdap_get_groups_done, req, 600, &state->op);

+                       sdap_get_groups_done, req,

+                       sdap_go_get_int(state->opts->basic,

+                                       SDAP_NETWORK_TIMEOUT),

+                       &state->op);

      if (ret) {

          DEBUG(1, ("Failed to set up operation!\n"));

          tevent_req_error(req, ret);
@@ -2086,7 +2092,10 @@

  

      /* FIXME: get timeouts from configuration, for now 10 minutes */

      ret = sdap_op_add(state, state->ev, state->sh, msgid,

-                       sdap_get_initgr_done, req, 600, &state->op);

+                       sdap_get_initgr_done, req,

+                       sdap_go_get_int(state->opts->basic,

+                                       SDAP_NETWORK_TIMEOUT),

+                       &state->op);

      if (ret) {

          DEBUG(1, ("Failed to set up operation!\n"));

          tevent_req_error(req, ret);

@@ -35,17 +35,22 @@

  struct sss_dp_callback {

      struct sss_dp_callback *prev;

      struct sss_dp_callback *next;

-     sss_dp_callback_t callback;

+ 

      struct sss_dp_req *sdp_req;

+ 

+     sss_dp_callback_t callback;

      void *callback_ctx;

  };

  

  struct sss_dp_req {

      struct tevent_context *ev;

-     struct sss_dp_callback *cb_list;

      DBusPendingCall *pending_reply;

  

      char *key;

+ 

+     struct tevent_timer *tev;

+     struct sss_dp_callback *cb_list;

+ 

      dbus_uint16_t err_maj;

      dbus_uint32_t err_min;

      char *err_msg;
@@ -63,18 +68,61 @@

  static int sss_dp_req_destructor(void *ptr)

  {

      struct sss_dp_req *sdp_req = talloc_get_type(ptr, struct sss_dp_req);

+     struct sss_dp_callback *cb, *next;

      hash_key_t key;

  

-     /* No callbacks to invoke. Destroy the hash entry */

+     /* Destroy any timer if present */

+     if (sdp_req->tev) {

+         talloc_zfree(sdp_req->tev);

+     }

+ 

+     /* Cancel Dbus pending reply if still pending */

+     if (sdp_req->pending_reply) {

+         dbus_pending_call_cancel(sdp_req->pending_reply);

+         sdp_req->pending_reply = NULL;

+     }

+ 

+     /* Destroy the hash entry */

      key.type = HASH_KEY_STRING;

      key.str = sdp_req->key;

      int hret = hash_delete(dp_requests, &key);

      if (hret != HASH_SUCCESS) {

-         DEBUG(0, ("Could not clear entry from request queue\n"));

          /* This should never happen */

-         return EIO;

+         DEBUG(0, ("Could not clear entry from request queue\n"));

      }

-     return EOK;

+ 

+     /* Free any remaining callback */

+     if (sdp_req->err_maj == DP_ERR_OK) {

+         sdp_req->err_maj = DP_ERR_FATAL;

+         sdp_req->err_min = EIO;

+         sdp_req->err_msg = discard_const_p(char, "Internal Error");

+     }

+ 

+     cb = sdp_req->cb_list;

+     while (cb) {

+         cb->callback(sdp_req->err_maj,

+                      sdp_req->err_min,

+                      sdp_req->err_msg,

+                      cb->callback_ctx);

+         next = cb->next;

+         talloc_free(cb);

+         cb = next;

+     }

+ 

+     return 0;

+ }

+ 

+ static void sdp_req_timeout(struct tevent_context *ev,

+                             struct tevent_timer *te,

+                             struct timeval t, void *ptr)

+ {

+     struct sss_dp_req *sdp_req = talloc_get_type(ptr, struct sss_dp_req);

+ 

+     sdp_req->err_maj = DP_ERR_FATAL;

+     sdp_req->err_min = ETIMEDOUT;

+     sdp_req->err_msg = discard_const_p(char, "Timed out");

+ 

+     talloc_free(sdp_req);

  }

  

  static int sss_dp_get_reply(DBusPendingCall *pending,
@@ -86,31 +134,33 @@

                                     struct tevent_timer *te,

                                     struct timeval t, void *ptr)

  {

-     struct sss_dp_req *sdp_req;

+     struct sss_dp_req *sdp_req = talloc_get_type(ptr, struct sss_dp_req);

      struct sss_dp_callback *cb;

      struct timeval tv;

      struct tevent_timer *tev;

  

-     sdp_req = talloc_get_type(ptr, struct sss_dp_req);

-     if (!sdp_req) {

-         /* We didn't receive an sss_dp_req? */

-         return;

-     }

+     /* eventually free the original request timeout */

+     talloc_zfree(sdp_req->tev);

  

      cb = sdp_req->cb_list;

+     /* Remove the callback from the list, the caller may free it, within the

+      * callback. */

+     talloc_set_destructor((TALLOC_CTX *)cb, NULL);

+     DLIST_REMOVE(sdp_req->cb_list, cb);

+ 

      cb->callback(sdp_req->err_maj,

                   sdp_req->err_min,

                   sdp_req->err_msg,

                   cb->callback_ctx);

  

-     /* Free the callback memory and remove it from the list */

-     talloc_zfree(cb);

- 

      /* Call the next callback if needed */

      if (sdp_req->cb_list != NULL) {

          tv = tevent_timeval_current();

-         tev = tevent_add_timer(sdp_req->ev, sdp_req, tv,

-                               sss_dp_invoke_callback, sdp_req);

+         /* don't allocate on sdp_req, cause you can't free a timer event from

+          * within the handler, so if you try to free sdp_req later from within

+          * the handler, the free may fail */

+         tev = tevent_add_timer(sdp_req->ev, NULL, tv,

+                                sss_dp_invoke_callback, sdp_req);

          if (!te) {

              /* Out of memory or other serious error */

              goto done;
@@ -119,7 +169,7 @@

          return;

      }

  

-     /* No more callbacks to invoke. Destroy the hash entry */

+     /* No more callbacks to invoke. Destroy the request */

  done:

      talloc_zfree(sdp_req);

  }
@@ -134,6 +184,9 @@

  

      sdp_req = talloc_get_type(ptr, struct sss_dp_req);

  

+     /* prevent trying to cancel a reply that we already received */

+     sdp_req->pending_reply = NULL;

+ 

      ret = sss_dp_get_reply(pending,

                             &sdp_req->err_maj,

                             &sdp_req->err_min,
@@ -199,6 +252,7 @@

      hash_key_t key;

      hash_value_t value;

      TALLOC_CTX *tmp_ctx;

+     struct timeval tv;

      struct sss_dp_req *sdp_req;

      struct sss_dp_callback *cb;

  
@@ -265,6 +319,7 @@

           * Add an additional callback if needed and return

           */

          DEBUG(2, ("Identical request in progress\n"));

+ 

          if (callback) {

              /* We have a new request asking for a callback */

              sdp_req = talloc_get_type(value.ptr, struct sss_dp_req);
@@ -287,8 +342,9 @@

              DLIST_ADD_END(sdp_req->cb_list, cb, struct sss_dp_callback *);

              talloc_set_destructor((TALLOC_CTX *)cb, sss_dp_callback_destructor);

          }

+ 

          ret = EOK;

-         goto done;

+         break;

  

      case HASH_ERROR_KEY_NOT_FOUND:

          /* No such request in progress
@@ -298,31 +354,48 @@

                                            be_type, filter, timeout,

                                            callback, callback_ctx,

                                            &sdp_req);

-         if (ret == EOK) {

-             value.type = HASH_VALUE_PTR;

-             value.ptr = sdp_req;

-             hret = hash_enter(dp_requests, &key, &value);

-             if (hret != HASH_SUCCESS) {

-                 DEBUG(0, ("Could not store request query (%s)",

-                           hash_error_string(hret)));

-                 ret = EIO;

-                 goto done;

-             }

+         if (ret != EOK) {

+             goto done;

+         }

+ 

+         value.type = HASH_VALUE_PTR;

+         value.ptr = sdp_req;

+         hret = hash_enter(dp_requests, &key, &value);

+         if (hret != HASH_SUCCESS) {

+             DEBUG(0, ("Could not store request query (%s)",

+                       hash_error_string(hret)));

+             talloc_zfree(sdp_req);

+             ret = EIO;

+             goto done;

+         }

+ 

+         sdp_req->key = talloc_strdup(sdp_req, key.str);

  

-             sdp_req->key = talloc_strdup(sdp_req, key.str);

-             talloc_set_destructor((TALLOC_CTX *)sdp_req, sss_dp_req_destructor);

+         /* don't allocate on sdp_req, cause you can't free a timer

+          * event from within the handler, so if you try to free

+          * sdp_req later from within the handler, the free may fail */

+         tv = tevent_timeval_current_ofs(timeout, 0);

+         sdp_req->tev = tevent_add_timer(sdp_req->ev, NULL, tv,

+                                         sdp_req_timeout, sdp_req);

+         if (!sdp_req->tev) {

+             DEBUG(0, ("Out of Memory!?"));

+             talloc_zfree(sdp_req);

+             ret = ENOMEM;

+             goto done;

          }

+ 

+         talloc_set_destructor((TALLOC_CTX *)sdp_req, sss_dp_req_destructor);

+ 

+         ret = EOK;

          break;

  

      default:

          DEBUG(0,("Could not query request list (%s)\n",

                    hash_error_string(hret)));

+         talloc_zfree(sdp_req);

          ret = EIO;

-         goto done;

      }

  

-     ret = EOK;

- 

  done:

      talloc_zfree(tmp_ctx);

      return ret;
@@ -395,13 +468,13 @@

          return EIO;

      }

  

-     sdp_req = talloc_zero(NULL, struct sss_dp_req);

+     sdp_req = talloc_zero(rctx, struct sss_dp_req);

      if (!sdp_req) {

          dbus_message_unref(msg);

          return ENOMEM;

      }

- 

      sdp_req->ev = rctx->ev;

+     sdp_req->pending_reply = pending_reply;

  

      if (callback) {

          cb = talloc_zero(memctx, struct sss_dp_callback);

@@ -2645,26 +2645,28 @@

      nctx = talloc_get_type(cctx->rctx->pvt_ctx, struct nss_ctx);

      gctx = nctx->gctx;

  

- retry:

-     if (gctx->cur >= gctx->num) goto none;

- 

-     gdom = &gctx->doms[gctx->cur];

+     do {

+         if (gctx->cur >= gctx->num) goto none;

  

-     n = gdom->res->count - gdom->cur;

-     if (n == 0 && (gctx->cur+1 < gctx->num)) {

-         gctx->cur++;

          gdom = &gctx->doms[gctx->cur];

+ 

          n = gdom->res->count - gdom->cur;

-     }

+         if (n == 0 && (gctx->cur+1 < gctx->num)) {

+             gctx->cur++;

+             gdom = &gctx->doms[gctx->cur];

+             n = gdom->res->count - gdom->cur;

+         }

  

-     if (!n) goto none;

+         if (!n) goto none;

  

-     msgs = &(gdom->res->msgs[gdom->cur]);

+         msgs = &(gdom->res->msgs[gdom->cur]);

  

-     ret = fill_grent(cctx->creq->out, gdom->domain, nctx, true, msgs, num, &n);

-     if (ret == ENOENT) goto retry;

+         ret = fill_grent(cctx->creq->out, gdom->domain, nctx, true, msgs, num, &n);

+ 

+         gdom->cur += n;

+ 

+     } while(ret == ENOENT);

  

-     gdom->cur += n;

      return ret;

  

  none:

file modified
+2 -2
@@ -6,7 +6,7 @@

  "Project-Id-Version: pl\n"

  "Report-Msgid-Bugs-To: sssd-devel@lists.fedorahosted.org\n"

  "POT-Creation-Date: 2009-09-25 13:57-0400\n"

- "PO-Revision-Date: 2009-09-16 17:06+0200\n"

+ "PO-Revision-Date: 2009-09-26 12:24+0200\n"

  "Last-Translator: Piotr Drąg <piotrdrag@gmail.com>\n"

  "Language-Team: Polish <fedora-trans-pl@redhat.com>\n"

  "MIME-Version: 1.0\n"
@@ -27,4 +27,4 @@

  

  #: pam_sss.c:611

  msgid "Reenter new Password: "

- msgstr "Ponownie podaj nowe hasło: "

+ msgstr "Proszę ponownie podać nowe hasło: "