From: Christian Korber Date: Tue, 28 Apr 2026 07:19:30 +0000 (+0200) Subject: luci-base: set password also for rpcd user X-Git-Url: http://git.99rst.org/?a=commitdiff_plain;h=b33ede60468e71ca5033aae09696eb0ac2531619;p=openwrt-luci.git luci-base: set password also for rpcd user This change allows the root user to change also rpcd logins via administration tab in system. This changes `setPassword` in a way that existing calls to it fall back to change unix passwords. The goal of this commit is to prepare the environment to add password policy (password length, valid property, special characters, etc) to the administration tab. Signed-off-by: Christian Korber --- diff --git a/modules/luci-base/root/usr/share/rpcd/ucode/luci b/modules/luci-base/root/usr/share/rpcd/ucode/luci index 57a96da141..de6a769bbd 100644 --- a/modules/luci-base/root/usr/share/rpcd/ucode/luci +++ b/modules/luci-base/root/usr/share/rpcd/ucode/luci @@ -46,6 +46,69 @@ function callPackageVersionCheck(pkg) { return version; } +function set_new_pwd(user, pwd) { + const ctx = cursor(); + let cmd, fd, value; + + cmd = sprintf('/usr/sbin/uhttpd -m %s', shellquote(pwd)); + fd = popen(cmd); + value = trim(fd.read('line')); + + fd.close(); + + ctx.foreach('rpcd', 'login', s => { + if (s.username == user) { + ctx.set('rpcd', s['.name'], 'password', value); + ctx.commit(); + } + }); +} + +function check_oldpwd(user, pwd) { + let cmd, fd, value; + const ctx = cursor(); + let valid = false; + + cmd = sprintf('/usr/sbin/uhttpd -m %s', shellquote(pwd)); + fd = popen(cmd); + value = trim(fd.read('line')); + fd.close(); + + ctx.foreach('rpcd', 'login', s => { + if (s.username == user && s.password == value) + valid = true; + }); + + return valid; +} + +function check_user(source, entry) { + let found = false; + + switch (source) { + case 'unix': { + const fd = open('/etc/passwd'); + + for (let line = fd.read('line'); length(line); line = fd.read('line')) { + let user = split(line, /:/)[0]; + if (user == entry) + found = true; + } + break; + } + + case 'rpcd': { + const ctx = cursor(); + ctx.foreach('rpcd', 'login', s => { + if (s.username == entry) + found = true; + }); + } + break; + } + return found; +} + const methods = { getVersion: { call: function(request) { @@ -469,14 +532,58 @@ const methods = { }, setPassword: { - args: { username: 'root', password: 'password' }, + args: { + username: 'root', + password: 'password', + oldpassword: '', + rpcd: false, + }, call: function(request) { - const u = shellquote(request.args.username); - const p = shellquote(request.args.password); + const user = request.args.username; + const pwd = request.args.password; + const oldpwd = request.args.oldpassword; + const type = request.args.rpcd == true ? 'rpcd' : 'unix'; + const known_user = check_user(type, user); + const uci = cursor(); - return { - result: system(`(echo ${p}; sleep 1; echo ${p}) | /bin/busybox passwd ${u} >/dev/null 2>&1`) == 0 - }; + if (type == 'unix') { + const u = shellquote(user); + const p = shellquote(pwd); + + return { + result: system(`(echo ${p}; sleep 1; echo ${p}) | /bin/busybox passwd ${u} >/dev/null 2>&1`) == 0 + }; + } + + if (!access('/usr/sbin/uhttpd', 'x')) + return { + result: 0 , + msg: "uhttpd not installed" + }; + + if (known_user) { + if (!oldpwd) + return { result: 0 }; + + /* + * check if login is valid + */ + if (!check_oldpwd(user, oldpwd)) + return { result: 0 }; + } else { + /* + * create user to keep logic of luci-app-acl + */ + const sid = uci.add('rpcd', 'login'); + uci.set('rpcd', sid, 'username', user); + uci.commit('rpcd'); + } + + /* + * encrypt password and assign it to rpcd login + */ + set_new_pwd(user, pwd); + return { result: 1 }; } },