From: Christian Korber Date: Fri, 24 Apr 2026 13:19:26 +0000 (+0200) Subject: luci-mod-system: unify password change X-Git-Url: http://git.99rst.org/?a=commitdiff_plain;h=331948ff365505c6fd6e6d8a9567f112f7936961;p=openwrt-luci.git luci-mod-system: unify password change A flag is added to choose if Password of rpcd user is changed or unix user. If rpc is chosen the old password has to be specified. Signed-off-by: Christian Korber --- diff --git a/modules/luci-mod-system/htdocs/luci-static/resources/view/system/password.js b/modules/luci-mod-system/htdocs/luci-static/resources/view/system/password.js index eb9d4a6d76..91bbd3161d 100644 --- a/modules/luci-mod-system/htdocs/luci-static/resources/view/system/password.js +++ b/modules/luci-mod-system/htdocs/luci-static/resources/view/system/password.js @@ -2,11 +2,17 @@ 'require view'; 'require dom'; 'require ui'; +'require fs'; +'require uci'; 'require form'; 'require rpc'; var formData = { - password: { + data: { + rpc_user: null, + user: null, + rpcd: null, + oldpw: null, pw1: null, pw2: null } @@ -15,8 +21,8 @@ var formData = { var callSetPassword = rpc.declare({ object: 'luci', method: 'setPassword', - params: [ 'username', 'password' ], - expect: { result: false } + params: [ 'username', 'password', 'oldpassword', 'rpcd' ], + expect: { result: 1 } }); return view.extend({ @@ -40,13 +46,66 @@ return view.extend({ return true; }, - render: function() { - var m, s, o; + load: function() { + return Promise.all([ + L.resolveDefault(fs.stat('/usr/sbin/uhttpd'), null), + fs.lines('/etc/passwd'), + uci.load('rpcd') + ]); + }, + + render: function([has_uhttpd, passwd]) { + var m, s, o, rpcd; + + const known_unix_users = {}; - m = new form.JSONMap(formData, _('Router Password'), _('Changes the administrator password for accessing the device')); + for (let p of passwd) { + const parts = p.split(/:/); + + if (parts.length >= 7) + known_unix_users[parts[0]] = true; + } + + m = new form.JSONMap(formData, _('Password'), _('Changes the password for accessing the device as (rpcd) user')); m.readonly = !L.hasViewPermission(); - s = m.section(form.NamedSection, 'password', 'password'); + s = m.section(form.NamedSection, 'data', 'data'); + + if (has_uhttpd) { + let logins = []; + + uci.sections('rpcd', 'login', s => logins.push(s.username)); + + rpcd = s.option(form.Flag, 'rpcd', _('Change password for rpcd user')); + rpcd.default = false; + + o = s.option(form.Value, 'rpc_user', _('rpcd username')); + for (let user of logins) { + if (user == 'root') + continue; + + o.value(user, _('%s').format(user)); + } + o.rmempty = false; + o.depends({ 'rpcd': '1' }); + + o = s.option(form.Value, 'user', _('Router username')); + for (let user in known_unix_users) + o.value(user, _('%s').format(user)); + o.rmempty = false; + o.depends({ 'rpcd': '0' }); + + o = s.option(form.Value, 'oldpw', _('Old Password')); + o.password = true; + o.depends({ 'rpcd': '1' }); + } + + if (!has_uhttpd) { + o = s.option(form.Value, 'user', _('Router username')); + for (let user in known_unix_users) + o.value(user); + o.rmempty = false; + } o = s.option(form.Value, 'pw1', _('Password')); o.password = true; @@ -72,22 +131,39 @@ return view.extend({ var map = document.querySelector('.cbi-map'); return dom.callClassMethod(map, 'save').then(function() { - if (formData.password.pw1 == null || formData.password.pw1.length == 0) + let rpc_user = formData.data.rpc_user; + let user = formData.data.user; + let rpcd = formData.data.rpcd; + let oldpw = formData.data.oldpw; + + if (rpc_user && (oldpw == null || oldpw.length == 0)) + return; + + if (formData.data.pw1 == null || formData.data.pw1.length == 0) return; - if (formData.password.pw1 != formData.password.pw2) { + if (formData.data.pw1 != formData.data.pw2) { ui.addNotification(null, E('p', _('Given password confirmation did not match, password not changed!')), 'danger'); return; } - return callSetPassword('root', formData.password.pw1).then(function(success) { + return callSetPassword( + rpc_user ? rpc_user : user, + formData.data.pw1, + oldpw ? oldpw : '', + rpcd ? true : false, + ).then(function(success) { if (success) ui.addNotification(null, E('p', _('The system password has been successfully changed.')), 'info'); else ui.addNotification(null, E('p', _('Failed to change the system password.')), 'danger'); - formData.password.pw1 = null; - formData.password.pw2 = null; + formData.data.rpc_user = null; + formData.data.user = null; + formData.data.rpcd = null; + formData.data.pw1 = null; + formData.data.pw2 = null; + formData.data.oldpw = null; dom.callClassMethod(map, 'render'); }); diff --git a/modules/luci-mod-system/root/usr/share/rpcd/acl.d/luci-mod-system.json b/modules/luci-mod-system/root/usr/share/rpcd/acl.d/luci-mod-system.json index fc633f4750..55de850325 100644 --- a/modules/luci-mod-system/root/usr/share/rpcd/acl.d/luci-mod-system.json +++ b/modules/luci-mod-system/root/usr/share/rpcd/acl.d/luci-mod-system.json @@ -2,13 +2,20 @@ "luci-mod-system-config": { "description": "Grant access to system configuration", "read": { + "cgi-io": [ "read" ], + "file": { + "/etc/passwd": [ "read" ] + }, "ubus": { "luci": [ "getLEDs", "getTimezones", "getUSBDevices", "getUnixtime" ], "rc": [ "list" ] }, - "uci": [ "luci", "system" ] + "uci": [ "luci", "system", "rpcd" ] }, "write": { + "file": { + "/usr/sbin/uhttpd -m *": [ "exec" ] + }, "ubus": { "luci": [ "setLocaltime", "setPassword" ], "rc": [ "init" ]