Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ gem 'audited', '~> 5.0', '!= 5.1.0'
gem 'will_paginate', '~> 3.3'
gem 'ancestry', '~> 4.0'
gem 'scoped_search', '>= 4.1.10', '< 5'
gem 'ldap_fluff', '>= 0.7.0', '< 1.0'
gem 'ldap_fluff', '>= 0.9.0', '< 1.0'
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Packaging was updated in theforeman/foreman-packaging@e80816f.

gem 'apipie-rails', '>= 0.8.0', '< 2'
gem 'apipie-dsl', '>= 2.6.2'
# Pin rdoc to prevent updating bundled psych (https://github.com/ruby/rdoc/commit/ebe185c8775b2afe844eb3da6fa78adaa79e29a4)
Expand Down
3 changes: 2 additions & 1 deletion app/controllers/api/v2/auth_source_ldaps_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ def show
param :usergroup_sync, :bool, :desc => N_("sync external user groups on login")
param :tls, :bool
param :groups_base, String, :desc => N_("groups base DN")
param :use_netgroups, :bool, :desc => N_("use NIS netgroups instead of posix groups, applicable only when server_type is posix or free_ipa")
param :use_netgroups, :bool, :desc => N_("use NIS netgroups instead of posix groups, applicable only when server_type is posix or free_ipa. Deprecated in favor of ldap_group_membership = nis_netgroups"), :deprecated => true
param :ldap_group_membership, AuthSourceLdap::GROUP_MEMBERSHIP_TYPES.keys, :desc => N_("type of group membership to use, applicable only when server_type is posix, free_ipa or netiq. Option rfc4519 is only applicable when server_type is posix.")
param :server_type, AuthSourceLdap::SERVER_TYPES.keys, :desc => N_("type of the LDAP server")
param :ldap_filter, String, :desc => N_("LDAP filter")
param_group :taxonomies, ::Api::V2::BaseController
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,27 @@ def auth_source_ldap_params_filter
:server_type,
:tls,
:usergroup_sync,
:use_netgroups
:use_netgroups,
:ldap_group_membership

add_taxonomix_params_filter(filter)
end
end
end

def auth_source_ldap_params
self.class.auth_source_ldap_params_filter.filter_params(params, parameter_filter_context)
filtered = self.class.auth_source_ldap_params_filter.filter_params(params, parameter_filter_context)
if filtered.key?("use_netgroups")
Foreman::Deprecation.deprecation_warning("3.18", "`use_netgroups` parameter is deprecated, use `ldap_group_membership` instead.")

expected = filtered["use_netgroups"] ? %w(nis_netgroups) : %w(posix rfc4519)
if filtered["ldap_group_membership"].blank?
filtered["ldap_group_membership"] = expected.first
elsif !expected.include?(filtered["ldap_group_membership"])
::Rails.logger.warn("Conflicting values for `use_netgroups` and `ldap_group_membership` parameters provided, ignoring `use_netgroups`.")
end
filtered.delete("use_netgroups")
end
filtered
end
end
28 changes: 24 additions & 4 deletions app/models/auth_sources/auth_source_ldap.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ class AuthSourceLdap < AuthSource
SERVER_TYPES = { :free_ipa => 'FreeIPA', :active_directory => 'Active Directory',
:posix => 'POSIX', :netiq => "NetIQ"}

GROUP_MEMBERSHIP_TYPES = { :posix => 'POSIX', :rfc4519 => 'POSIX + RFC4519', :nis_netgroups => 'NIS Netgroups' }

extend FriendlyId
friendly_id :name
include Parameterizable::ByIdName
Expand All @@ -35,10 +37,11 @@ class AuthSourceLdap < AuthSource
validates :account_password, :length => {:maximum => 69}, :allow_nil => true
validates :port, :presence => true, :numericality => {:only_integer => true}
validates :server_type, :presence => true, :inclusion => { :in => SERVER_TYPES.keys.map(&:to_s) }
validates :ldap_group_membership, :presence => true, :inclusion => { :in => :allowed_group_membership_types }, :if => proc { |auth| %w[posix netiq free_ipa].include?(auth.server_type.to_s) }
validate :validate_ldap_filter, :unless => proc { |auth| auth.ldap_filter.blank? }

before_validation :strip_ldap_attributes
before_validation :sanitize_use_netgroups
before_validation :sanitize_group_membership
after_initialize :set_defaults, if: :new_record?

scoped_search :on => :name, :complete_value => :true
Expand Down Expand Up @@ -92,7 +95,8 @@ def to_config(login = nil, password = nil)
:anon_queries => account.blank?, :service_user => service_user(login),
:service_pass => use_user_login_for_service? ? password : account_password,
:instrumentation_service => ActiveSupport::Notifications,
:use_netgroups => use_netgroups }
:use_netgroups => ldap_group_membership == 'nis_netgroups',
:use_rfc4519_group_membership => ldap_group_membership == 'rfc4519' }
end

def encryption_config
Expand Down Expand Up @@ -195,8 +199,13 @@ def strip_ldap_attributes
end
end

def sanitize_use_netgroups
self.use_netgroups = false if server_type.to_s == 'active_directory'
def sanitize_group_membership
if server_type.to_s == 'active_directory'
self.ldap_group_membership = nil
else
self.ldap_group_membership ||= 'posix'
end

true
end

Expand Down Expand Up @@ -276,4 +285,15 @@ def use_user_login_for_service?
def service_user(login)
use_user_login_for_service? ? account.sub("$login", login) : account
end

def allowed_group_membership_types
case server_type.to_s
when 'posix'
GROUP_MEMBERSHIP_TYPES.keys.map(&:to_s)
when 'netiq', 'free_ipa'
['posix', 'nis_netgroups']
when 'active_directory'
[]
end
end
end
6 changes: 5 additions & 1 deletion app/views/api/v2/auth_source_ldaps/main.json.rabl
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,8 @@ extends "api/v2/auth_source_ldaps/base"

attributes :host, :port, :account, :base_dn, :ldap_filter, :attr_login, :attr_firstname, :attr_lastname,
:attr_mail, :attr_photo, :onthefly_register, :usergroup_sync, :tls, :server_type, :groups_base,
:use_netgroups, :created_at, :updated_at
:ldap_group_membership, :created_at, :updated_at

node :use_netgroups do |auth_source_ldap|
auth_source_ldap.ldap_group_membership == 'nis_netgroups'
end
11 changes: 10 additions & 1 deletion app/views/auth_source_ldaps/_form.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,16 @@
<%= password_f f, :account_password, :help_inline => _("Use this account to authenticate, <i>optional</i>").html_safe, :unset => action_name == "edit" %>
<%= text_f f, :base_dn, :label => _("Base DN"), :size => "col-md-8", :label_help => base_dn_help_data[@auth_source_ldap.server_type], :data => { :help => base_dn_help_data } %>
<%= text_f f, :groups_base, :label => _("Groups base DN"), :size => "col-md-8", :label_help => groups_base_dn_help_data[@auth_source_ldap.server_type], :data => { :help => groups_base_dn_help_data } %>
<%= checkbox_f f, :use_netgroups, :help_inline => _("Use NIS netgroups instead of posix groups."), :label_help => _('By default we map user groups to standard LDAP Group objects. FreeIPA and POSIX LDAP server types supports alternative way of grouping users through Netgroups. Enable this checkbox if using Netgroups is preferred instead of standard groups.') %>

<%= select_f f, :ldap_group_membership, AuthSourceLdap::GROUP_MEMBERSHIP_TYPES, :first, :last,
{ },
{ :label => _('Group membership type'),
:help_inline => _("Controls which mechanism will be used for looking up users' group membership in LDAP."),
:label_help => "<ul>
<li><b>#{_("POSIX")}</b> - #{_("Use the memberuid attribute to map user groups to standard LDAP Group objects.")}</li>
<li><b>#{_("POSIX + RFC4519")}</b> - #{_("Use group membership based on the groupOfNames and groupOfUniqueNames attributes as defined in RFC4519 in addition to POSIX groups. Some POSIX LDAP servers support an alternative way of using the groupOfNames - member and groupOfUniqueNames - uniqueMember attributes to model group membership.")}</li>
<li><b>#{_("NIS Netgroups")}</b> - #{_("Use NIS netgroups instead of posix groups. FreeIPA and POSIX LDAP server types supports alternative way of grouping users through Netgroups.")}</li>
Comment thread
adamruzicka marked this conversation as resolved.
Outdated
</ul>".html_safe } %>

<%= textarea_f f, :ldap_filter, :label => _("LDAP filter"), :help_block => _("Custom LDAP search filter, <i>optional</i>").html_safe, :size => "col-md-8" %>
<%= checkbox_f f, :onthefly_register,
Expand Down
14 changes: 14 additions & 0 deletions db/migrate/20250528092104_extend_ldap_group_membership_options.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
class ExtendLdapGroupMembershipOptions < ActiveRecord::Migration[7.0]
def up
add_column :auth_sources, :ldap_group_membership, :string
AuthSourceLdap.where.not(server_type: 'active_directory').update_all(ldap_group_membership: 'posix')
AuthSourceLdap.where(use_netgroups: true).update_all(ldap_group_membership: 'nis_netgroups')
remove_column :auth_sources, :use_netgroups
end

def down
add_column :auth_sources, :use_netgroups, :boolean, :default => false
AuthSourceLdap.where(ldap_group_membership: 'nis_netgroups').update_all(use_netgroups: true)
remove_column :auth_sources, :ldap_group_membership
end
end
2 changes: 2 additions & 0 deletions script/lint/lint_core_config.js
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ module.exports = {
'poolsurl',
'popstate',
'posinset',
'posix',
'pqr',
'ptable',
'puppetclass',
Expand All @@ -137,6 +138,7 @@ module.exports = {
'repo',
'resize',
'rex',
'rfc4519',
'rhel',
'safemode',
'sbs',
Expand Down
1 change: 1 addition & 0 deletions test/factories/auth_source_ldap.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
attr_lastname { 'daho' }
port { '389' }
server_type { 'posix' }
ldap_group_membership { 'posix' }
end

trait :posix
Expand Down
14 changes: 12 additions & 2 deletions test/models/auth_sources/auth_source_ldap_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,21 @@ def setup
end

test "it enforces use_netgroups to false for active directory" do
auth_source_ldap.use_netgroups = true
auth_source_ldap.ldap_group_membership = 'nis_netgroups'
auth_source_ldap.server_type = :active_directory

assert auth_source_ldap.valid?
refute auth_source_ldap.use_netgroups
assert_nil auth_source_ldap.ldap_group_membership
end

test "it propagates group membership to the config" do
auth_source_ldap.ldap_group_membership = 'rfc4519'
assert auth_source_ldap.to_config[:use_rfc4519_group_membership]
refute auth_source_ldap.to_config[:use_netgroups]

auth_source_ldap.ldap_group_membership = 'nis_netgroups'
refute auth_source_ldap.to_config[:use_rfc4519_group_membership]
assert auth_source_ldap.to_config[:use_netgroups]
end

test "return nil if login is blank or password is blank" do
Expand Down
24 changes: 20 additions & 4 deletions webpack/assets/javascripts/foreman_auth_source.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,14 +83,30 @@ function updateLdapAccountHelp(selectedType) {

export function changeLdapServerType() {
const type = $('#auth_source_ldap_server_type').val();
$('#auth_source_ldap_use_netgroups')
.closest('.form-group')
.toggle(type !== 'active_directory');
const membershipType = $('#auth_source_ldap_ldap_group_membership');

membershipType.closest('.form-group').toggle(type !== 'active_directory');

if (type !== 'active_directory') {
const rfc4519 = $(
'#auth_source_ldap_ldap_group_membership option[value="rfc4519"]'
);

if (type !== 'posix') {
rfc4519.attr('disabled', 'disabled');
if (membershipType.find(':selected').val() === 'rfc4519') {
membershipType.val('posix').trigger('change');
}
} else {
rfc4519.removeAttr('disabled');
}
}

updateLdapAccountHelp(type);
}

$(document).ready(() => {
if (window.location.pathname.match('auth_source_ldaps/i')) {
if (window.location.pathname.match(/auth_source_ldaps/i)) {
Comment on lines 93 to 109
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wonder if this ever worked

> window.location.pathname
'/auth_source_ldaps/new'

> window.location.pathname.match('auth_source_ldaps/i')
null

> window.location.pathname.match(/auth_source_ldaps/i)
['auth_source_ldaps', index: 1, input: '/auth_source_ldaps/new', groups: undefined]

changeLdapServerType();
}
});