mirror of
https://github.com/YunoHost/yunohost.git
synced 2024-09-03 20:06:10 +02:00
Merge pull request #403 from YunoHost/allow_ssh_user
Add commands to allow/disallow a yunohost user to connect in ssh
This commit is contained in:
commit
79ee4cb13d
2 changed files with 88 additions and 1 deletions
|
@ -203,6 +203,30 @@ user:
|
||||||
extra:
|
extra:
|
||||||
pattern: *pattern_mailbox_quota
|
pattern: *pattern_mailbox_quota
|
||||||
|
|
||||||
|
### ssh_user_enable_ssh()
|
||||||
|
allow-ssh:
|
||||||
|
action_help: Allow the user to uses ssh
|
||||||
|
api: POST /ssh/user/enable-ssh
|
||||||
|
configuration:
|
||||||
|
authenticate: all
|
||||||
|
arguments:
|
||||||
|
username:
|
||||||
|
help: Username of the user
|
||||||
|
extra:
|
||||||
|
pattern: *pattern_username
|
||||||
|
|
||||||
|
### ssh_user_disable_ssh()
|
||||||
|
disallow-ssh:
|
||||||
|
action_help: Disallow the user to uses ssh
|
||||||
|
api: POST /ssh/user/disable-ssh
|
||||||
|
configuration:
|
||||||
|
authenticate: all
|
||||||
|
arguments:
|
||||||
|
username:
|
||||||
|
help: Username of the user
|
||||||
|
extra:
|
||||||
|
pattern: *pattern_username
|
||||||
|
|
||||||
### user_info()
|
### user_info()
|
||||||
info:
|
info:
|
||||||
action_help: Get user information
|
action_help: Get user information
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
"""
|
"""
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
|
import pwd
|
||||||
import json
|
import json
|
||||||
import errno
|
import errno
|
||||||
import crypt
|
import crypt
|
||||||
|
@ -56,6 +57,7 @@ def user_list(auth, fields=None):
|
||||||
'cn': 'fullname',
|
'cn': 'fullname',
|
||||||
'mail': 'mail',
|
'mail': 'mail',
|
||||||
'maildrop': 'mail-forward',
|
'maildrop': 'mail-forward',
|
||||||
|
'loginShell': 'shell',
|
||||||
'mailuserquota': 'mailbox-quota'
|
'mailuserquota': 'mailbox-quota'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,7 +73,7 @@ def user_list(auth, fields=None):
|
||||||
raise MoulinetteError(errno.EINVAL,
|
raise MoulinetteError(errno.EINVAL,
|
||||||
m18n.n('field_invalid', attr))
|
m18n.n('field_invalid', attr))
|
||||||
else:
|
else:
|
||||||
attrs = ['uid', 'cn', 'mail', 'mailuserquota']
|
attrs = ['uid', 'cn', 'mail', 'mailuserquota', 'loginShell']
|
||||||
|
|
||||||
result = auth.search('ou=users,dc=yunohost,dc=org',
|
result = auth.search('ou=users,dc=yunohost,dc=org',
|
||||||
'(&(objectclass=person)(!(uid=root))(!(uid=nobody)))',
|
'(&(objectclass=person)(!(uid=root))(!(uid=nobody)))',
|
||||||
|
@ -81,6 +83,12 @@ def user_list(auth, fields=None):
|
||||||
entry = {}
|
entry = {}
|
||||||
for attr, values in user.items():
|
for attr, values in user.items():
|
||||||
if values:
|
if values:
|
||||||
|
if attr == "loginShell":
|
||||||
|
if values[0].strip() == "/bin/false":
|
||||||
|
entry["ssh_allowed"] = False
|
||||||
|
else:
|
||||||
|
entry["ssh_allowed"] = True
|
||||||
|
|
||||||
entry[user_attrs[attr]] = values[0]
|
entry[user_attrs[attr]] = values[0]
|
||||||
|
|
||||||
uid = entry[user_attrs['uid']]
|
uid = entry[user_attrs['uid']]
|
||||||
|
@ -435,6 +443,36 @@ def user_info(auth, username):
|
||||||
raise MoulinetteError(167, m18n.n('user_info_failed'))
|
raise MoulinetteError(167, m18n.n('user_info_failed'))
|
||||||
|
|
||||||
|
|
||||||
|
def user_allow_ssh(auth, username):
|
||||||
|
"""
|
||||||
|
Allow YunoHost user connect as ssh.
|
||||||
|
|
||||||
|
Keyword argument:
|
||||||
|
username -- User username
|
||||||
|
"""
|
||||||
|
# TODO it would be good to support different kind of shells
|
||||||
|
|
||||||
|
if not _get_user_for_ssh(auth, username):
|
||||||
|
raise MoulinetteError(errno.EINVAL, m18n.n('user_unknown', user=username))
|
||||||
|
|
||||||
|
auth.update('uid=%s,ou=users' % username, {'loginShell': '/bin/bash'})
|
||||||
|
|
||||||
|
|
||||||
|
def user_disallow_ssh(auth, username):
|
||||||
|
"""
|
||||||
|
Disallow YunoHost user connect as ssh.
|
||||||
|
|
||||||
|
Keyword argument:
|
||||||
|
username -- User username
|
||||||
|
"""
|
||||||
|
# TODO it would be good to support different kind of shells
|
||||||
|
|
||||||
|
if not _get_user_for_ssh(auth, username) :
|
||||||
|
raise MoulinetteError(errno.EINVAL, m18n.n('user_unknown', user=username))
|
||||||
|
|
||||||
|
auth.update('uid=%s,ou=users' % username, {'loginShell': '/bin/false'})
|
||||||
|
|
||||||
|
|
||||||
def _convertSize(num, suffix=''):
|
def _convertSize(num, suffix=''):
|
||||||
for unit in ['K', 'M', 'G', 'T', 'P', 'E', 'Z']:
|
for unit in ['K', 'M', 'G', 'T', 'P', 'E', 'Z']:
|
||||||
if abs(num) < 1024.0:
|
if abs(num) < 1024.0:
|
||||||
|
@ -470,3 +508,28 @@ def _hash_user_password(password):
|
||||||
|
|
||||||
salt = '$6$' + salt + '$'
|
salt = '$6$' + salt + '$'
|
||||||
return '{CRYPT}' + crypt.crypt(str(password), salt)
|
return '{CRYPT}' + crypt.crypt(str(password), salt)
|
||||||
|
|
||||||
|
|
||||||
|
def _get_user_for_ssh(auth, username, attrs=None):
|
||||||
|
if username == "admin":
|
||||||
|
admin_unix = pwd.getpwnam("admin")
|
||||||
|
return {
|
||||||
|
'username': 'admin',
|
||||||
|
'fullname': '',
|
||||||
|
'mail': '',
|
||||||
|
'ssh_allowed': admin_unix.pw_shell.strip() != "/bin/false",
|
||||||
|
'shell': admin_unix.pw_shell,
|
||||||
|
'home_path': admin_unix.pw_dir,
|
||||||
|
}
|
||||||
|
|
||||||
|
# TODO escape input using https://www.python-ldap.org/doc/html/ldap-filter.html
|
||||||
|
user = auth.search('ou=users,dc=yunohost,dc=org',
|
||||||
|
'(&(objectclass=person)(uid=%s))' % username,
|
||||||
|
attrs)
|
||||||
|
|
||||||
|
assert len(user) in (0, 1)
|
||||||
|
|
||||||
|
if not user:
|
||||||
|
return None
|
||||||
|
|
||||||
|
return user[0]
|
||||||
|
|
Loading…
Add table
Reference in a new issue