Skip to content
Open
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
27 changes: 27 additions & 0 deletions data/templates/faillock.conf.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# PAM faillock configuration managed by userd
# Do not edit manually - changes will be overwritten

# Global settings
dir = /var/run/faillock
audit
silent
no_log_info

{% if security_policies %}
# Role-based security policies
{% for role, policy in security_policies.items() %}
{% if policy.max_login_attempts %}
# {{ role }} role settings

Choose a reason for hiding this comment

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

does faillock support individual config per group/role/user ?

Copy link
Author

Choose a reason for hiding this comment

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

This is applied per role.

deny = {{ policy.max_login_attempts }}
unlock_time = 900 # 15 minutes
{% endif %}
{% endfor %}
Comment on lines +12 to +18
Copy link

Copilot AI Nov 25, 2025

Choose a reason for hiding this comment

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

The PAM faillock configuration template only uses the first role's max_login_attempts value due to the way the template is structured. The loop iterates over all roles but each iteration overwrites the previous deny setting. This means only the last processed role's setting will be effective. Consider restructuring the template to either apply different settings per user or use a global setting based on the most restrictive policy.

Suggested change
{% for role, policy in security_policies.items() %}
{% if policy.max_login_attempts %}
# {{ role }} role settings
deny = {{ policy.max_login_attempts }}
unlock_time = 900 # 15 minutes
{% endif %}
{% endfor %}
{% set max_attempts_list = [] %}
{% for role, policy in security_policies.items() %}
{% if policy.max_login_attempts %}
{% set _ = max_attempts_list.append(policy.max_login_attempts) %}
{% endif %}
{% endfor %}
{% if max_attempts_list %}
deny = {{ max_attempts_list | min }}
unlock_time = 900 # 15 minutes
{% else %}
# No max_login_attempts set in any role, use default
deny = 5
unlock_time = 900
{% endif %}

Copilot uses AI. Check for mistakes.
{% else %}
# Default settings when no policies are configured
deny = 5
unlock_time = 900
{% endif %}

# Additional settings
fail_interval = 900
root_unlock_time = 900
26 changes: 26 additions & 0 deletions userd/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Makefile for sonic-host-userd

.PHONY: all clean install build-cpp

# Default target
all: build-cpp

# Build C++ components
build-cpp:
mkdir -p build
cd build && cmake ../src && make

# Clean build artifacts
clean:
rm -rf build

# Install (called by debian packaging)
install: build-cpp
mkdir -p $(DESTDIR)/usr/local/bin
cp build/userd $(DESTDIR)/usr/local/bin/userd
chmod +x $(DESTDIR)/usr/local/bin/userd

# For development/testing
install-local: build-cpp
sudo cp build/userd /usr/local/bin/userd
sudo chmod +x /usr/local/bin/userd
5 changes: 5 additions & 0 deletions userd/debian/changelog
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
sonic-host-userd (1.0-1) UNRELEASED; urgency=low

* Initial release

-- SONiC Maintainers <[email protected]> Mon, 11 Aug 2025 08:00:00 +0000
Copy link

Copilot AI Nov 25, 2025

Choose a reason for hiding this comment

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

[nitpick] The changelog indicates a future date (Mon, 11 Aug 2025) which is unusual. Typically changelog dates should reflect the actual release date or use the current date. Consider using the current date or a placeholder that will be updated upon release.

Suggested change
-- SONiC Maintainers <[email protected]> Mon, 11 Aug 2025 08:00:00 +0000
-- SONiC Maintainers <[email protected]> TODO: update upon release

Copilot uses AI. Check for mistakes.
1 change: 1 addition & 0 deletions userd/debian/compat
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
11
11 changes: 11 additions & 0 deletions userd/debian/control
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
Source: sonic-host-userd
Maintainer: SONiC Maintainers <[email protected]>
Section: misc
Priority: optional
Standards-Version: 0.1
Build-Depends: debhelper (>=11), cmake, g++, pkg-config, libcrypt-dev, nlohmann-json3-dev, libswsscommon-dev

Package: sonic-host-userd
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}, sonic-host-services-data, libswsscommon
Description: SONiC host userd binary
20 changes: 20 additions & 0 deletions userd/debian/copyright
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: sonic-host-userd
Source: https://github.com/Azure/sonic-buildimage

Files: *
Copyright: 2025 Microsoft Corporation
License: Apache-2.0

License: Apache-2.0
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
.
http://www.apache.org/licenses/LICENSE-2.0
.
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
1 change: 1 addition & 0 deletions userd/debian/install
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
build/userd /usr/local/bin/
20 changes: 20 additions & 0 deletions userd/debian/rules
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/usr/bin/make -f

%:
dh $@

override_dh_auto_build:
dh_auto_build
# Build C++ components
make build-cpp

override_dh_auto_install:
dh_auto_install
# Install C++ components
make install DESTDIR=$(CURDIR)/debian/sonic-host-userd

override_dh_installsystemd:
dh_installsystemd --no-start --name=sonic-host-userd

override_dh_usrlocal:
# Skip dh_usrlocal since we're intentionally installing to /usr/local/bin
15 changes: 15 additions & 0 deletions userd/debian/sonic-host-userd.service
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
[Unit]
Description=User management daemon
Requires=config-setup.service
After=config-setup.service
BindsTo=sonic.target
After=sonic.target

[Service]
Type=simple
ExecStart=/usr/local/bin/userd
Restart=always
RestartSec=5
Copy link

Copilot AI Nov 25, 2025

Choose a reason for hiding this comment

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

[nitpick] The service configuration has Restart=always with RestartSec=5, which means if the daemon crashes due to a configuration error or bug, it will restart indefinitely every 5 seconds. Consider adding StartLimitBurst and StartLimitIntervalSec to prevent endless restart loops that could impact system stability.

Suggested change
RestartSec=5
RestartSec=5
StartLimitBurst=3
StartLimitIntervalSec=60

Copilot uses AI. Check for mistakes.

[Install]
WantedBy=sonic.target
31 changes: 31 additions & 0 deletions userd/src/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
cmake_minimum_required(VERSION 3.10)
project(sonic-host-userd)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# Include directories (SONiC standard paths)
include_directories(/usr/include/swss)
include_directories(/usr/include)

# Compiler flags
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Werror")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -g -O0")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O2")

# Add executable
add_executable(userd userd.cpp)

# Link libraries
target_link_libraries(userd
swsscommon
pthread
crypt
)

# Install target
install(TARGETS userd
RUNTIME DESTINATION /usr/local/bin
)


Loading
Loading