class Idmap_DomainToBackend(Model): idmap_dtb_domain = models.OneToOneField( Idmap_Domain, on_delete=models.deletion.CASCADE, to_field='idmap_domain_name', unique=True, null=True, verbose_name=_('pre-Windows 2000 Domain Name'), ) idmap_dtb_idmap_backend = models.CharField( choices=choices.IDMAP_CHOICES(), default='rid', max_length=120, verbose_name=_("idmap backend for domain"), )
class LDAP(DirectoryServiceBase): ldap_hostname = models.CharField( verbose_name=_("Hostname"), max_length=120, help_text=_("The name or IP address of the LDAP server"), blank=True ) ldap_basedn = models.CharField( verbose_name=_("Base DN"), max_length=120, help_text=_( "The default base Distinguished Name (DN) to use for " "searches, eg dc=test,dc=org"), blank=True ) ldap_binddn = models.CharField( verbose_name=_("Bind DN"), max_length=256, help_text=_( "The distinguished name with which to bind to the " "directory server, e.g. cn=admin,dc=test,dc=org"), blank=True ) ldap_bindpw = models.CharField( verbose_name=_("Bind password"), max_length=120, help_text=_("The credentials with which to bind."), blank=True ) ldap_anonbind = models.BooleanField( verbose_name=_("Allow Anonymous Binding"), default=False ) ldap_usersuffix = models.CharField( verbose_name=_("User Suffix"), max_length=120, help_text=_( "This parameter specifies the suffix that is used for " "users when these are added to the LDAP directory, e.g. " "ou=Users"), blank=True ) ldap_groupsuffix = models.CharField( verbose_name=_("Group Suffix"), max_length=120, help_text=_( "This parameter specifies the suffix that is used " "for groups when these are added to the LDAP directory, e.g. " "ou=Groups"), blank=True ) ldap_passwordsuffix = models.CharField( verbose_name=_("Password Suffix"), max_length=120, help_text=_( "This parameter specifies the suffix that is used for " "passwords when these are added to the LDAP directory, e.g. " "ou=Passwords"), blank=True ) ldap_machinesuffix = models.CharField( verbose_name=_("Machine Suffix"), max_length=120, help_text=_( "This parameter specifies the suffix that is used for " "machines when these are added to the LDAP directory, e.g. " "ou=Computers"), blank=True ) ldap_sudosuffix = models.CharField( verbose_name=_("SUDO Suffix"), max_length=120, help_text=_( "This parameter specifies the suffix that is used for " "the SUDO configuration in the LDAP directory, e.g. " "ou=SUDOers"), blank=True ) ldap_kerberos_realm = models.ForeignKey( KerberosRealm, verbose_name=_("Kerberos Realm"), on_delete=models.SET_NULL, blank=True, null=True ) ldap_kerberos_principal = models.CharField( verbose_name=_("Kerberos Princpal"), max_length=255, blank=True ) ldap_ssl = models.CharField( verbose_name=_("Encryption Mode"), max_length=120, help_text=_( "This parameter specifies whether to use SSL/TLS, e.g." " on/off/start_tls" ), choices=choices.LDAP_SSL_CHOICES, default='off' ) ldap_certificate = models.ForeignKey( Certificate, verbose_name=_("Certificate"), on_delete=models.SET_NULL, blank=True, null=True, limit_choices_to={'cert_certificate__isnull': False, 'cert_privatekey__isnull': False} ) ldap_timeout = models.IntegerField( verbose_name=_("LDAP timeout"), help_text=_("Timeout for LDAP related commands."), default=10 ) ldap_dns_timeout = models.IntegerField( verbose_name=_("DNS timeout"), help_text=_("Timeout for LDAP DNS queries."), default=10 ) ldap_idmap_backend = models.CharField( verbose_name=_("Idmap Backend"), choices=choices.IDMAP_CHOICES(), max_length=120, help_text=_("Idmap backend for winbind."), default=enum_to_idmap(IDMAP_TYPE_LDAP) ) ldap_has_samba_schema = models.BooleanField( verbose_name=_("Samba Schema"), default=False ) ldap_auxiliary_parameters = models.TextField( verbose_name=_("Auxiliary Parameters"), blank=True, help_text=_("These parameters are added to nslcd.conf") ) ldap_schema = models.CharField( verbose_name=("Schema"), choices=choices.LDAP_SCHEMA_CHOICES, max_length=120, help_text=_("LDAP Schema type."), default=choices.LDAP_SCHEMA_CHOICES[0][0] ) ldap_enable = models.BooleanField( verbose_name=_("Enable"), default=False ) def __init__(self, *args, **kwargs): super(LDAP, self).__init__(*args, **kwargs) if self.ldap_bindpw: try: self.ldap_bindpw = notifier().pwenc_decrypt(self.ldap_bindpw) except Exception: log.debug( 'Failed to decrypt LDAP bind password', exc_info=True ) self.ldap_bindpw = '' self._ldap_bindpw_encrypted = False self.ds_type = DS_TYPE_LDAP self.ds_name = enum_to_directoryservice(self.ds_type) def save(self, *args, **kwargs): if self.ldap_bindpw and not self._ldap_bindpw_encrypted: self.ldap_bindpw = notifier().pwenc_encrypt( self.ldap_bindpw ) self._ldap_bindpw_encrypted = True super(LDAP, self).save(*args, **kwargs) class Meta: verbose_name = _("LDAP") verbose_name_plural = _("LDAP")
class ActiveDirectory(DirectoryServiceBase): ad_domainname = models.CharField( verbose_name=_("Domain Name (DNS/Realm-Name)"), max_length=120, help_text=_("Domain Name, eg example.com") ) ad_bindname = models.CharField( verbose_name=_("Domain Account Name"), max_length=120, help_text=_("Domain account name to bind as"), blank=True ) ad_bindpw = models.CharField( verbose_name=_("Domain Account Password"), max_length=120, help_text=_("Domain Account password."), blank=True ) ad_ssl = models.CharField( verbose_name=_("Encryption Mode"), max_length=120, help_text=_( "This parameter specifies whether to use SSL/TLS, e.g." " on/off/start_tls" ), choices=choices.LDAP_SSL_CHOICES, default='off' ) ad_certificate = models.ForeignKey( Certificate, verbose_name=_("Certificate"), on_delete=models.SET_NULL, blank=True, null=True, limit_choices_to={'cert_certificate__isnull': False, 'cert_privatekey__isnull': False} ) ad_verbose_logging = models.BooleanField( verbose_name=_("Verbose logging"), default=False ) ad_unix_extensions = models.BooleanField( verbose_name=_("UNIX extensions"), help_text=_("Set this if your Active Directory has UNIX extensions."), default=False ) ad_allow_trusted_doms = models.BooleanField( verbose_name=_("Allow Trusted Domains"), help_text=_("Set this if you want to allow Trusted Domains."), default=False ) ad_use_default_domain = models.BooleanField( verbose_name=_("Use Default Domain"), help_text=_( "Set this if you want to use the default " "domain for users and groups."), default=False ) ad_allow_dns_updates = models.BooleanField( verbose_name=_("Allow DNS updates"), help_text=_("Set this if you want to allow allow DNS updates."), default=True ) ad_disable_freenas_cache = models.BooleanField( verbose_name=_("Disable Active Directory user/group cache"), help_text=_( "Set this if you want to disable caching Active Directory users " "and groups. Use this option if you are experiencing slowness or " "having difficulty binding to the domain with a large number of " "users and groups."), default=False ) ad_site = models.CharField( verbose_name=_("Site Name"), max_length=120, help_text=_( "Name of Active Directory Site. This field will be automatically populated " "during the domain join process. If an AD site is not configured for the " "subnet where the NAS is located, the site name will be populated as " "'Default-First-Site-Name'"), blank=True, null=True ) ad_kerberos_realm = models.ForeignKey( KerberosRealm, verbose_name=_("Kerberos Realm"), on_delete=models.SET_NULL, blank=True, null=True ) ad_kerberos_principal = models.CharField( verbose_name=_("Kerberos Princpal"), max_length=255, help_text=_( "Kerberos principal to use for AD-related UI and middleware operations " "Field is populated with principals present in the system keytab. " "During the domain join process a keytab entry is generated for the " "AD Machine Account associated with the NAS. The name for this account " "is the netbios name of the server with a '$' appended to it. Once " "the NAS is joined to active directory, the bind credentials will be " "automatically cleared and all future operations carried out by the AD " "machine account, which has a restricted set of privileges in the AD domain."), blank=True, null=True ) ad_createcomputer = models.CharField( blank=True, max_length=255, verbose_name=_('Computer Account OU'), help_text=( 'If blank, then the default OU is used during computer account creation. ' 'Precreate the computer account in a specific OU. The OU string ' 'read from top to bottom without RDNs and delimited by a "/". ' 'E.g. "createcomputer=Computers/Servers/Unix NB: A backslash ' '"\" is used as escape at multiple levels and may need to be ' 'doubled or even quadrupled. It is not used as a separator.' ) ) ad_timeout = models.IntegerField( verbose_name=_("AD timeout"), help_text=_("Timeout for AD related commands."), default=60 ) ad_dns_timeout = models.IntegerField( verbose_name=_("DNS timeout"), help_text=_("Timeout for AD DNS queries."), default=60 ) ad_idmap_backend = models.CharField( verbose_name=_("Idmap backend"), choices=choices.IDMAP_CHOICES(), max_length=120, help_text=_("Idmap backend for winbind."), default=enum_to_idmap(IDMAP_TYPE_RID) ) ad_nss_info = models.CharField( max_length=120, blank=True, null=True, choices=choices.NSS_INFO_CHOICES, verbose_name=_("Winbind NSS Info"), help_text=_("This parameter is designed to control how Winbind " "retrieves Name Service Information to construct a user's " "home directory and login") ) ad_ldap_sasl_wrapping = models.CharField( verbose_name=_("SASL wrapping"), choices=choices.LDAP_SASL_WRAPPING_CHOICES, max_length=120, help_text=_("The client ldap sasl wrapping defines whether ldap " "traffic will be signed or signed and encrypted (sealed)." "This option is needed in the case of Domain Controllers " "enforcing the usage of signed LDAP connections (e.g. " "Windows 2000 SP3 or higher). LDAP sign and seal can be " "controlled with the registry key \"HKLM\System\\" "CurrentControlSet\\Services\\NTDS\\Parameters\\" "LDAPServerIntegrity\" on the Windows server side." ), default='plain' ) ad_enable = models.BooleanField( verbose_name=_("Enable"), default=False ) def __init__(self, *args, **kwargs): super(ActiveDirectory, self).__init__(*args, **kwargs) if self.ad_bindpw: try: self.ad_bindpw = notifier().pwenc_decrypt(self.ad_bindpw) except Exception: log.debug('Failed to decrypt AD bind password', exc_info=True) self.ad_bindpw = '' self._ad_bindpw_encrypted = False self.ds_type = DS_TYPE_ACTIVEDIRECTORY self.ds_name = enum_to_directoryservice(self.ds_type) def save(self, **kwargs): if self.ad_bindpw and not self._ad_bindpw_encrypted: self.ad_bindpw = notifier().pwenc_encrypt( self.ad_bindpw ) self._ad_bindpw_encrypted = True super(ActiveDirectory, self).save(**kwargs) class Meta: verbose_name = _("Active Directory") verbose_name_plural = _("Active Directory")
class ActiveDirectory(DirectoryServiceBase): ad_domainname = models.CharField( verbose_name=_("Domain Name (DNS/Realm-Name)"), max_length=120, help_text=_("Domain Name, eg example.com") ) ad_bindname = models.CharField( verbose_name=_("Domain Account Name"), max_length=120, help_text=_("Domain account name to bind as"), blank=True ) ad_bindpw = models.CharField( verbose_name=_("Domain Account Password"), max_length=120, help_text=_("Domain Account password."), blank=True ) ad_monitor_frequency = models.IntegerField( verbose_name=_("AD check connectivity frequency (seconds)"), default=60, validators=[MaxValueValidator(3600), MinValueValidator(30)], help_text=_("How often to verify that AD servers are active."), blank=False ) ad_recover_retry = models.IntegerField( verbose_name=_("How many recovery attempts"), default=10, validators=[MaxValueValidator(500), MinValueValidator(0)], help_text=_( "Number of times to attempt to recover the connection with AD " "server. If the value is 0, try forever."), blank=False ) ad_enable_monitor = models.BooleanField( verbose_name=_("Enable Monitoring"), help_text=_("Restart AD automatically if the service is disconnected."), default=False ) ad_ssl = models.CharField( verbose_name=_("Encryption Mode"), max_length=120, help_text=_( "This parameter specifies whether to use SSL/TLS, e.g." " on/off/start_tls" ), choices=choices.LDAP_SSL_CHOICES, default='off' ) ad_certificate = models.ForeignKey( Certificate, verbose_name=_("Certificate"), on_delete=models.SET_NULL, blank=True, null=True, limit_choices_to={'cert_certificate__isnull': False, 'cert_privatekey__isnull': False} ) ad_verbose_logging = models.BooleanField( verbose_name=_("Verbose logging"), default=False ) ad_unix_extensions = models.BooleanField( verbose_name=_("UNIX extensions"), help_text=_("Set this if your Active Directory has UNIX extensions."), default=False ) ad_allow_trusted_doms = models.BooleanField( verbose_name=_("Allow Trusted Domains"), help_text=_("Set this if you want to allow Trusted Domains."), default=False ) ad_use_default_domain = models.BooleanField( verbose_name=_("Use Default Domain"), help_text=_( "Set this if you want to use the default " "domain for users and groups."), default=False ) ad_allow_dns_updates = models.BooleanField( verbose_name=_("Allow DNS updates"), help_text=_("Set this if you want to allow allow DNS updates."), default=True ) ad_disable_freenas_cache = models.BooleanField( verbose_name=_("Disable Active Directory user/group cache"), help_text=_( "Set this if you want to disable caching Active Directory users " "and groups. Use this option if you are experiencing slowness or " "having difficulty binding to the domain with a large number of " "users and groups."), default=False ) ad_userdn = models.CharField( verbose_name=_("User Base"), max_length=1024, help_text=_("DN of the user container in AD."), blank=True, null=True ) ad_groupdn = models.CharField( verbose_name=_("Group Base"), max_length=1024, help_text=_("DN of the group container in AD."), blank=True, null=True ) ad_site = models.CharField( verbose_name=_("Site Name"), max_length=120, help_text=_("Name of site to use."), blank=True, null=True ) ad_dcname = models.CharField( verbose_name=_("Domain Controller"), max_length=120, help_text=_("FQDN of the domain controller to use."), blank=True, null=True ) ad_gcname = models.CharField( verbose_name=_("Global Catalog Server"), max_length=120, help_text=_("FQDN of the global catalog server to use."), blank=True, null=True ) ad_kerberos_realm = models.ForeignKey( KerberosRealm, verbose_name=_("Kerberos Realm"), on_delete=models.SET_NULL, blank=True, null=True ) ad_kerberos_principal = models.ForeignKey( KerberosPrincipal, verbose_name=_("Kerberos Principal"), on_delete=models.SET_NULL, blank=True, null=True ) ad_timeout = models.IntegerField( verbose_name=_("AD timeout"), help_text=_("Timeout for AD related commands."), default=60 ) ad_dns_timeout = models.IntegerField( verbose_name=_("DNS timeout"), help_text=_("Timeout for AD DNS queries."), default=60 ) ad_idmap_backend = models.CharField( verbose_name=_("Idmap backend"), choices=choices.IDMAP_CHOICES(), max_length=120, help_text=_("Idmap backend for winbind."), default=enum_to_idmap(IDMAP_TYPE_RID) ) ad_nss_info = models.CharField( max_length=120, blank=True, null=True, choices=choices.NSS_INFO_CHOICES, verbose_name=_("Winbind NSS Info"), help_text=_("This parameter is designed to control how Winbind " "retrieves Name Service Information to construct a user's " "home directory and login") ) ad_ldap_sasl_wrapping = models.CharField( verbose_name=_("SASL wrapping"), choices=choices.LDAP_SASL_WRAPPING_CHOICES, max_length=120, help_text=_("The client ldap sasl wrapping defines whether ldap " "traffic will be signed or signed and encrypted (sealed)." "This option is needed in the case of Domain Controllers " "enforcing the usage of signed LDAP connections (e.g. " "Windows 2000 SP3 or higher). LDAP sign and seal can be " "controlled with the registry key \"HKLM\System\\" "CurrentControlSet\\Services\\NTDS\\Parameters\\" "LDAPServerIntegrity\" on the Windows server side." ), default='plain' ) ad_enable = models.BooleanField( verbose_name=_("Enable"), default=False ) def __init__(self, *args, **kwargs): super(ActiveDirectory, self).__init__(*args, **kwargs) if self.ad_bindpw: try: self.ad_bindpw = notifier().pwenc_decrypt(self.ad_bindpw) except Exception: log.debug('Failed to decrypt AD bind password', exc_info=True) self.ad_bindpw = '' self._ad_bindpw_encrypted = False self.ds_type = DS_TYPE_ACTIVEDIRECTORY self.ds_name = enum_to_directoryservice(self.ds_type) def save(self, **kwargs): if self.ad_bindpw and not self._ad_bindpw_encrypted: self.ad_bindpw = notifier().pwenc_encrypt( self.ad_bindpw ) self._ad_bindpw_encrypted = True super(ActiveDirectory, self).save(**kwargs) if not self.ad_kerberos_realm: from freenasUI.common.freenasldap import ( FreeNAS_ActiveDirectory, FLAGS_DBINIT ) try: FreeNAS_ActiveDirectory(flags=FLAGS_DBINIT) kr = KerberosRealm.objects.filter( krb_realm=self.ad_domainname.upper() ) if kr: kr = kr[0] else: kr = KerberosRealm() kr.krb_realm = self.ad_domainname.upper() kr.save() self.ad_kerberos_realm = kr super(ActiveDirectory, self).save() except Exception as e: log.debug( "ActiveDirectory: Unable to create kerberos realm: %s", e, exc_info=True ) class Meta: verbose_name = _("Active Directory") verbose_name_plural = _("Active Directory")
class LDAP(DirectoryServiceBase): ldap_hostname = models.CharField( verbose_name=_("Hostname"), max_length=120, help_text=_("The name or IP address of the LDAP server"), blank=True) ldap_basedn = models.CharField( verbose_name=_("Base DN"), max_length=120, help_text=_("The default base Distinguished Name (DN) to use for " "searches, eg dc=test,dc=org"), blank=True) ldap_binddn = models.CharField( verbose_name=_("Bind DN"), max_length=256, help_text=_("The distinguished name with which to bind to the " "directory server, e.g. cn=admin,dc=test,dc=org"), blank=True) ldap_bindpw = models.CharField( verbose_name=_("Bind password"), max_length=120, help_text=_("The credentials with which to bind."), blank=True) ldap_anonbind = models.BooleanField( verbose_name=_("Allow Anonymous Binding"), default=False) ldap_kerberos_realm = models.ForeignKey(KerberosRealm, verbose_name=_("Kerberos Realm"), on_delete=models.SET_NULL, blank=True, null=True) ldap_kerberos_principal = models.CharField( verbose_name=_("Kerberos Princpal"), max_length=255, blank=True) ldap_ssl = models.CharField( verbose_name=_("Encryption Mode"), max_length=120, help_text=_("This parameter specifies whether to use SSL/TLS, e.g." " on/off/start_tls"), choices=choices.LDAP_SSL_CHOICES, default='off') ldap_certificate = models.ForeignKey(Certificate, verbose_name=_("Certificate"), on_delete=models.SET_NULL, blank=True, null=True, limit_choices_to={ 'cert_certificate__isnull': False, 'cert_privatekey__isnull': False }) ldap_validate_certificates = models.BooleanField( verbose_name=_("Perform strict certificate validation"), default=True, help_text= _("Request certificate from remote LDAP server. If no certificate is provided " "or a bad certificate is provided, immediately terminate LDAP session. " "This parameter corresponds with the ldap.conf parameter TLS_REQCERT demand. " "TLS_REQCERT allow is set if unchecked. ")) ldap_disable_freenas_cache = models.BooleanField( verbose_name=_("Disable LDAP user/group cache"), help_text= _("Set to disable caching LDAP users and groups in large LDAP environments. " "When caching is disabled, LDAP users and groups do not appear in dropdown " "menus, but are still accepted when manually entered."), default=False) ldap_timeout = models.IntegerField( verbose_name=_("LDAP timeout"), help_text=_("Timeout for LDAP related commands."), default=10) ldap_dns_timeout = models.IntegerField( verbose_name=_("DNS timeout"), help_text=_("Timeout for LDAP DNS queries."), default=10) ldap_idmap_backend = models.CharField( verbose_name=_("Idmap Backend"), choices=choices.IDMAP_CHOICES(), max_length=120, help_text=_("Idmap backend for winbind."), default=enum_to_idmap(IDMAP_TYPE_LDAP)) ldap_has_samba_schema = models.BooleanField(verbose_name=_("Samba Schema"), default=False) ldap_auxiliary_parameters = models.TextField( verbose_name=_("Auxiliary Parameters"), blank=True, help_text=_("These parameters are added to nslcd.conf")) ldap_schema = models.CharField(verbose_name=("Schema"), choices=choices.LDAP_SCHEMA_CHOICES, max_length=120, help_text=_("LDAP Schema type."), default=choices.LDAP_SCHEMA_CHOICES[0][0]) ldap_enable = models.BooleanField(verbose_name=_("Enable"), default=False) def __init__(self, *args, **kwargs): super(LDAP, self).__init__(*args, **kwargs) if self.ldap_bindpw: try: self.ldap_bindpw = notifier().pwenc_decrypt(self.ldap_bindpw) except Exception: log.debug('Failed to decrypt LDAP bind password', exc_info=True) self.ldap_bindpw = '' self._ldap_bindpw_encrypted = False self.ds_type = DS_TYPE_LDAP self.ds_name = enum_to_directoryservice(self.ds_type) def save(self, *args, **kwargs): if self.ldap_bindpw and not self._ldap_bindpw_encrypted: self.ldap_bindpw = notifier().pwenc_encrypt(self.ldap_bindpw) self._ldap_bindpw_encrypted = True super(LDAP, self).save(*args, **kwargs) class Meta: verbose_name = _("LDAP") verbose_name_plural = _("LDAP")