users: Avoid username conflicts with system users

When creating or renaming a user, check if the new username is in use by
any system user.
This commit is contained in:
James Valleroy 2016-07-14 07:05:47 -04:00 committed by Sunil Mohan Adapa
parent ec68446eec
commit 3a69958165
No known key found for this signature in database
GPG Key ID: 36C361440C9BC971
2 changed files with 40 additions and 0 deletions

View File

@ -22,6 +22,7 @@ Forms for first boot module.
import json import json
import logging import logging
import requests import requests
import subprocess
from django import forms from django import forms
from django.contrib import auth from django.contrib import auth
@ -46,6 +47,18 @@ class State1Form(auth.forms.UserCreationForm):
self.request = kwargs.pop('request') self.request = kwargs.pop('request')
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
def clean(self):
"""Check for username collisions with system users."""
username = self.cleaned_data['username']
try:
subprocess.run(['getent', 'passwd', username], check=True)
# Exit code 0 means that the username is already in use.
raise ValidationError(_('Username is reserved'))
except subprocess.CalledProcessError:
pass
return super().clean()
def save(self, commit=True): def save(self, commit=True):
"""Create and log the user in.""" """Create and log the user in."""
user = super().save(commit=commit) user = super().save(commit=commit)

View File

@ -15,10 +15,13 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
# #
import subprocess
from django import forms from django import forms
from django.contrib import messages from django.contrib import messages
from django.contrib.auth.models import User, Group from django.contrib.auth.models import User, Group
from django.contrib.auth.forms import UserCreationForm, SetPasswordForm from django.contrib.auth.forms import UserCreationForm, SetPasswordForm
from django.core.exceptions import ValidationError
from django.utils.translation import ugettext as _, ugettext_lazy from django.utils.translation import ugettext as _, ugettext_lazy
from plinth import actions from plinth import actions
@ -55,6 +58,18 @@ class CreateUserForm(UserCreationForm):
self.request = request self.request = request
super(CreateUserForm, self).__init__(*args, **kwargs) super(CreateUserForm, self).__init__(*args, **kwargs)
def clean(self):
"""Check for username collisions with system users."""
username = self.cleaned_data['username']
try:
subprocess.run(['getent', 'passwd', username], check=True)
# Exit code 0 means that the username is already in use.
raise ValidationError(_('Username is reserved'))
except subprocess.CalledProcessError:
pass
return super().clean()
def save(self, commit=True): def save(self, commit=True):
"""Save the user model and create LDAP user if required.""" """Save the user model and create LDAP user if required."""
user = super(CreateUserForm, self).save(commit) user = super(CreateUserForm, self).save(commit)
@ -116,6 +131,18 @@ class UserUpdateForm(forms.ModelForm):
self.username = username self.username = username
super(UserUpdateForm, self).__init__(*args, **kwargs) super(UserUpdateForm, self).__init__(*args, **kwargs)
def clean(self):
"""Check for username collisions with system users."""
username = self.cleaned_data['username']
try:
subprocess.run(['getent', 'passwd', username], check=True)
# Exit code 0 means that the username is already in use.
raise ValidationError(_('Username is reserved'))
except subprocess.CalledProcessError:
pass
return super().clean()
def save(self, commit=True): def save(self, commit=True):
"""Update LDAP user name and groups after saving user model.""" """Update LDAP user name and groups after saving user model."""
user = super(UserUpdateForm, self).save(commit) user = super(UserUpdateForm, self).save(commit)