OpenWrt Forum Archive

Topic: Multiuser Openwrt/luci

The content of this topic has been archived on 27 Apr 2018. There are no obvious gaps in this topic, but there may still be some posts missing at the end.

I have implemented a multi-user setup for Openwrt/Luci. Not only does it provide multi user access, it also allows the root user to ..

- add/remove users
- select what group the user/s shall belong to
- choose whether or not the user/s should have ssh access
- choose what parts of the luci ui are available to the user on an individual basis

This can all be done from the luci ui by the root user smile

I would like to release it as a luci module but there are a few issues that make adding it or more so removing it as a package difficult to obtain with out inconvenience. The main problem is that there is mods to the dispatcher.lua file, one to allow ALL system users to sign in and another to remove parts of the index from the ctx.tree . I have also moved some menus around in the ui layout (controllers) to accommodate the multi-user setup. So the problems are.. the menus would remain in the order i've set for the multi-user setup ...which is not really a big deal. however the major problem is the luci-core and/or the luci-admin-full pkg's ( which ever one contains the dispatcher.lua file) would need to be removed and then reinstalled because the dispatcher.lua file would be removed with multi-user package.


I would like to work with the developers on this to improve it a little and incorporate it into openwrt as a maintainable and convenient multi-user pkg for the openwrt/luci systems. The src code is available for those who wish to help

bump ..bump  I have a multi-user implimentation completed. I can add/remove users from the  luci ui as well as set which menus the user can access, ssh permissions ..etc. The users can set their own password without effecting the root password from the ui and never has root access to the device. I would like to make a few improvments to it and possibly ad it as a ipk option for luci. The package no longer has any dependencies and with a few conditional statements added in the dispatcher, index and serviceclt can be added and removed with no negitive effects to the standard luci functionality.

I also have a pure lua ftp server i would like to possibly add as well, I could really use some constructive critism if Jow or any of the other devs would like to help out.

We could certainly add the required changes to the dispatcher to standard luci. I suggest to make a PR against openwrt/luci on Github, so we can discuss it there.

Ok sounds good jow. I will get things cleaned up and commented then add it to git this week. I look forward to working with you

I have added the project to Github, here https://github.com/Hostle/openwrt-luci-multi-user I only included the files pertaining to the project to make it easier to see what i have done so far. I commented the dispatcher.lua in regards to what i have added, comments are at the top of the file. The changes to servicectl.lua and index lua a pretty evident. It works fine for me, although the code is still a little rudimentary. I think it could be improved allot by utilizing cbi/uci to do allot more, however i am not so familiar with the functions available nor how to use them properly. If nothing else it serves as a great proof of concept, with a little polishing I think it should work pretty good.

(Last edited by hostle19 on 5 Mar 2015, 15:01)

Hi,
I compiled your openwrt-luci-multi-user from github after the entry in the "edit user" I get the following error:

/usr/lib/lua/luci/dispatcher.lua:526: Failed to execute function dispatcher target for entry '/admin/users'.
The called action terminated with an exception:
/usr/lib/lua/luci/dispatcher.lua:526: Failed to execute cbi dispatcher target for entry '/admin/users/users'.
The called action terminated with an exception:
/usr/lib/lua/luci/cbi.lua:311: Unable to read UCI data: users
stack traceback:
    [C]: in function 'assert'
    /usr/lib/lua/luci/dispatcher.lua:526: in function 'dispatch'
    /usr/lib/lua/luci/dispatcher.lua:182: in function </usr/lib/lua/luci/dispatcher.lua:181>

You can ask for direction to solve the problem?

That error is telling you that the config file for the users module is missing. Just add an empty file "/etc/config/users" and it should work. Its strange that file is missing, you must have got the src before i was finished working on it. You should update the src and rebuild, i fix a few small bugs before i uploaded the complete package and you'll want the new src. I have added the src to the LuCI src so you can build it just as you would any luci pkg. Just add the feed and update then you will see the pkg in the menuconfig under LuCI >> Modules called "admin-multi-user".

## LuCI 0.12 / 14.07 Barrier Breaker Branch ##
src-git luci https://github.com/Hostle/openwrt-luci- … ;luci-0.12

or the development branch

## LuCI trunk / Chaos Calmer Branch ##
src-git luci https://github.com/Hostle/openwrt-luci-multi-user.git

just add the appropriate feed to your "feeds.conf.default" and then put a "#" in front of the original luci feed and then update the luci feed

./scripts/feeds update luci
./scripts/feeds install -a -p luci

then you should see the new pkg in the menuconfig under LuCI >> Modules > admin-multi-user

(Last edited by hostle19 on 18 Mar 2015, 02:32)

Thank you for your quick and substantial response. I complie BB rev. 44874 with openwrt-luci-multi-user built-in image.
touch /etc/config/users - solved the problem or mkdir -p files/etc/config and touch files/etc/config/users before compilation.

I still question whether there is a possibility to hide submenu eg. network -> switch in some way?

There is a security problem;). If the user has a hidden menu system can still get to it by modifying the link, eg. /admin/system/startup.

m_koziol wrote:

Thank you for your quick and substantial response. I complie BB rev. 44874 with openwrt-luci-multi-user built-in image.
touch /etc/config/users - solved the problem or mkdir -p files/etc/config and touch files/etc/config/users before compilation.

I still question whether there is a possibility to hide submenu eg. network -> switch in some way?

There is a security problem;). If the user has a hidden menu system can still get to it by modifying the link, eg. /admin/system/startup.

I will look into why the config file is not being included in the build, that's strange.

To your question, I am hoping Jow or someone with more intimate knowledge of the dispatcher can point out a way to hide sub-menu's instead of removing the entire tree from the index.This is way I have not enable the option to hide sub-menus from the interface. For now the only option is to remove the entire tree from the index. I am sure there is away to ignore a sub menu and keep from adding it to the tree but I just haven't found it yet smile time has been limited lately so when i get some free time I will look into it further.

Just to clarify, you are not able to access a sub-menu of a menu you have checked as hidden in the user configuration ? you are trying to add them in manually to the dispatcher like remove_idx(ctx.tree, "startup")... correct ?

(Last edited by hostle19 on 18 Mar 2015, 15:27)

I have added the ability to hide sub menus and fixed the direct url access so that when a menu is hidden it CAN NOT be accessed by using the url directly as suggested in the previous post. One last thing to do is to enable hiding the top layer of the menus without disabling the sub menu's from that section as well... Status, System ..etc.

@Jow .. I know your a busy man but I would love some productive criticism or even just criticism so I can move toward adding this to luci for all members to benefit from.

I have finished and tested the code. As far as I am concerned I have completed a full blown multi-user setup for luci/openwrt. I have added the ability to hide ANY menu from ANY non root user ... finally smile

Available Features
- add/remove users from the luci ui
- set ssh access to on or off on a per user basis
- set user type to user(basic ssh permissions) or admin(elevated ssh permissions)  per user basis
- set what luci ui menus options are visible and available for new users on a per user basis
- initial password for new users is openwrt, users can set there own password once logged in

Build Instructions
Just add the feed and update then you will see the pkg in the menuconfig under LuCI >> Modules called "admin-multi-user".

## LuCI 0.12 / 14.07 Barrier Breaker Branch ##
src-git luci https://github.com/Hostle/openwrt-luci- … ;luci-0.12

or the development branch
## LuCI trunk / Chaos Calmer Branch ##
src-git luci https://github.com/Hostle/openwrt-luci-multi-user.git

just add the appropriate feed to your "feeds.conf.default" and then put a "#" in front of the original luci feed and then update the luci feed

./scripts/feeds update luci
./scripts/feeds install -a -p luci

then you should see the new pkg in the menuconfig under LuCI >> Modules > admin-multi-user


The mods to the luci src are minimal, and luci functions fine when package is removed. Aside for the code added I have to rename a few files in the luasrc in the admin-full and admin-base but again this does not effect luci functionality . I think this could easily be pushed to the luci src and become a valuable tool in which the openwrt community could really benefit from. I have my own respo set up were the code can be fetched and built but ultimately I would like to see it become part of the luci repository or at least have the necessary changes made to the luci src to accommodate the multi-user package.

(Last edited by hostle19 on 3 Oct 2015, 02:49)

As there been any progress in getting a patch integrated into the trunk? I've tried the implementation and it's been working great.

Unfortunately not, I have added the git respo as requested by Jow but I  have not had any sort of input from him or any other developers. It needs a little work before a patch or package can be made that would allow a seamless installation/removal process. I would bet Jow or any other luci developer could work it in very quickly, but sadly they seem to be too busy to take a look sad

Hi hostle seems you make my day, i was looking for a luci multiuser interface solution, your solution seems to fit perfectly to my needs, can i count on you to some support during my test?

jow wrote:

We could certainly add the required changes to the dispatcher to standard luci. I suggest to make a PR against openwrt/luci on Github, so we can discuss it there.

hostle19 wrote:

Unfortunately not, I have added the git respo as requested by Jow but I  have not had any sort of input from him or any other developers. It needs a little work before a patch or package can be made that would allow a seamless installation/removal process.

Well, actually Jow asked for a Pull Request against the current Luci trunk.
https://github.com/openwrt/luci/pulls

Your github repo is nice, but as it seems to contain Luci from March 2015 plus your changes, it is not very practical to try use that for any merge, as it is too hard to figure out the differences to the current trunk.

The repo where you develop, should be a "fork" from Luci trunk, so that a pull request can be made easily.

You should also use git rebase to squash some of your 60 commits as they edit the same files back and forth, reflecting your development process.

I cloned your github repo and tried to figure out the changes.
Below is the summary based on diff against last existing commit before your changes:

perus@ub1510:/Openwrt/github/multiuser$ git diff  --stat 4ab6dce .
 README.md                                                                  |   7 +
 modules/luci-base/luasrc/controller/admin/servicectl.lua                   |  19 +-
 modules/luci-base/luasrc/dispatcher.lua                                    | 155 ++++++++++++-
 modules/luci-mod-admin-full/luasrc/controller/admin/index.lua              |  18 +-
 modules/luci-mod-admin-full/luasrc/controller/admin/network.lua            |   8 +-
 modules/luci-mod-admin-full/luasrc/controller/admin/system.lua             |   4 +-
 modules/luci-mod-admin-full/luasrc/model/cbi/admin_network/iface_add.lua   |   4 +-
 modules/luci-mod-admin-full/luasrc/model/cbi/admin_network/netroutes.lua   |  74 +++++++
 modules/luci-mod-admin-full/luasrc/model/cbi/admin_network/network.lua     |  71 ------
 modules/luci-mod-admin-full/luasrc/model/cbi/admin_network/network_tab.lua |  71 ++++++
 modules/luci-mod-admin-full/luasrc/model/cbi/admin_network/routes.lua      |  74 -------
 modules/luci-mod-admin-full/luasrc/model/cbi/admin_system/admin.lua        | 119 ----------
 modules/luci-mod-admin-full/luasrc/model/cbi/admin_system/admins.lua       | 119 ++++++++++
 modules/luci-mod-admin-full/luasrc/model/cbi/admin_system/system.lua       | 216 -------------------
 modules/luci-mod-admin-full/luasrc/model/cbi/admin_system/system_tab.lua   | 216 +++++++++++++++++++
 modules/luci-mod-admin-full/luasrc/view/admin_network/iface_overview.htm   |   4 +-
 modules/luci-mod-admin-multi-user/Makefile                                 |  10 +
 modules/luci-mod-admin-multi-user/luasrc/controller/admin/users.lua        |  53 +++++
 modules/luci-mod-admin-multi-user/luasrc/model/cbi/admin_users/passwd.lua  |  58 +++++
 modules/luci-mod-admin-multi-user/luasrc/model/cbi/admin_users/users.lua   | 113 ++++++++++
 modules/luci-mod-admin-multi-user/luasrc/users.lua                         | 552 +++++++++++++++++++++++++++++++++++++++++++++++
 modules/luci-mod-admin-multi-user/root/etc/uci-defaults/09_users           |  12 ++
 themes/luci-theme-bootstrap/luasrc/view/themes/bootstrap/header.htm        |   2 +-
 themes/luci-theme-openwrt/luasrc/view/themes/openwrt.org/header.htm        |   2 +-
 24 files changed, 1484 insertions(+), 497 deletions(-)

Based on that and on "git diff 4ab6dce ." I see roughly four different kind of changes:
1) renames of existing modules (network, routes, admin, system) and the fallout from that (themes, controller)
2) changes affecting the base (dispatcher, servicectl.lua and index.lua)
3) new multiuser module in luci-mod-admin-multi-user
4) documentation changes at README
(plus some unnecessary white space changes)

Are all the renames really necessary? Necessary in order to avoid some duplication in module paths?

I also think that the multiuser module might be a luci-application instead of a luci-module. As base files would be edited, the required generic changes (renames , changes to base) would be included already in the default luci, so to me it makes no sense to define this as an alternative to the normal luci. Instead the additional multiuser stuff looks like an add-on application (like statistics, DDNS etc.).

If you would like to get this included in Luci proper, I suggest that you
1) fork a new repo from Luci trunk
2) apply the changes in probably three logical commits (renames & related fallout, changes to base, new module) and clearly explain the reasoning in commit messages.
    (and skip the changes of documentation to include links to screenshots etc.)
    (skip also the extensive copyright/comments block in uci-defaults file that quadruples the size of that file)
3) create a Pull Request at Luci github

Using "git diff 4ab6dce . > multi.patch" it should be rather straightforward to create a patch for Luci in order to create the new commits.

Well, I did a trial import to trunk myself and also compiled and flashed it to trunk ar71xx/WNDR3700 router.

It seems to work, with some minor glitches (although "network" is disabled for an user, it is visible but no page can be opened from it, so the restriction seems to work).

I used a clone of your repo and "git diff 4ab6dce . " to create a patch file.
Then I did the 4 file renames manually and removed those actions from the patch file.
Then I tried applying the remaining patch, and it almost succeeded. Only 2-3 minor edits needed for changes done in trunk code since March 2015.
I also modified the new "material" theme, simplified the uci-defaults file and discarded the changes to readme file.
And I moved the new stuff from luci-modules to luci-applications.

I committed the changes in three commits, as I proposed in the previous message.
https://github.com/hnyman/luci/commits/multiuser

Downloadable links to the three patches for Luci trunk (as of 13 Jan 16):
https://github.com/hnyman/luci/commit/8 … 050b.patch
https://github.com/hnyman/luci/commit/3 … d7e0.patch
https://github.com/hnyman/luci/commit/1 … 9011.patch

At the first glance, I don't like the hard-coded permitted page/leaf names for status, system and network tabs in users.lua. That makes it more difficult in the long run to adapt into changes in core Luci.

Some of the changes, especially the renames to ensure unique names for pages/leafs, could probably be committed into the core luci right away. (although the page/leaf name names might be slightly tweaked first)

Parts of the code (user management page?) might need to be modified due to the recent link vs. CSRF token change). I did not try to check those aspects.

Also the copyright headers in the new module could be shortened (as was done by https://github.com/openwrt/luci/commit/ … ff4da26b7b a year ago )

I think that I will open a pull request about this for discussion purposes, so that Jow & others can participate and comment directly the code. Or will you do that?

(Last edited by hnyman on 13 Jan 2016, 16:41)

hnyman wrote:

Well, I did a trial import to trunk myself and also compiled and flashed it to trunk ar71xx/WNDR3700 router.

I think that I will open a pull request about this for discussion purposes, so that Jow & others can participate and comment directly the code. Or will you do that?

If you could do that that would be great, you seem to have much more experience using git then I do. I basically just threw this together for proof of concept, I think if could be improved a lot before actually being implemented into Luci. Also, just this past weekend I decided to make some changes to try and simplify things. The new method has far fewer moving parts and is much less invasive to the luci src. Basically I got rid of most of the modifications to the dispatcher.lua and the need for renaming.I did this by adding simple checks to determine if the user has privileges to use each index entry in the index() function of each controller.

\-- Copyright 2008 Steven Barth <steven@midlink.org>
-- Copyright 2011 Jo-Philipp Wich <jow@openwrt.org>
-- Licensed to the public under the Apache License 2.0.

module("luci.controller.admin.status", package.seeall)


function index()
    local fs = require "nixio.fs"

         function user(val)
       if not fs.access("/usr/lib/lua/luci/users.lua") then return true end

           local dsp = require "luci.dispatcher"
           local usw = require "luci.users"
           local user = dsp.get_user()
       if user == "root" then return true end
           local name = "status"

       local menu = {}
       menu = usw.hide_menus(user,name) or {}

         for i,v in pairs(menu) do
            if v == val then return true end
         end
         return false
      end

      entry({"admin", "status"}, alias("admin", "status", "overview"), _("Status"), 20).index = true
      entry({"admin", "status", "overview"}, template("admin_status/index"), _("Overview"), 1)

if user("Firewall") == true then
      entry({"admin", "status", "iptables"}, call("action_iptables"), _("Firewall"), 2).leaf = true
    end
if user("Routes") == true then
      entry({"admin", "status", "routes"}, template("admin_status/routes"), _("Routes"), 3)
    end
if user("System_log") == true then
      entry({"admin", "status", "syslog"}, call("action_syslog"), _("System Log"), 4)
    end
if user("Kernel_log") == true then
      entry({"admin", "status", "dmesg"}, call("action_dmesg"), _("Kernel Log"), 5)
    end
if user("Processes") == true then
      entry({"admin", "status", "processes"}, cbi("admin_status/processes"), _("Processes"), 6)
    end
if user("Realtime_graphs") == true then
      entry({"admin", "status", "realtime"}, alias("admin", "status", "realtime", "load"), _("Realtime Graphs"), 7)
      entry({"admin", "status", "realtime", "load"}, template("admin_status/load"), _("Load"), 1).leaf = true
      entry({"admin", "status", "realtime", "load_status"}, call("action_load")).leaf = true
      entry({"admin", "status", "realtime", "bandwidth"}, template("admin_status/bandwidth"), _("Traffic"), 2).leaf = true
      entry({"admin", "status", "realtime", "bandwidth_status"}, call("action_bandwidth")).leaf = true
      entry({"admin", "status", "realtime", "wireless"}, template("admin_status/wireless"), _("Wireless"), 3).leaf = true
      entry({"admin", "status", "realtime", "wireless_status"}, call("action_wireless")).leaf = true
      entry({"admin", "status", "realtime", "connections"}, template("admin_status/connections"), _("Connections"), 4).leaf = true
      entry({"admin", "status", "realtime", "connections_status"}, call("action_connections")).leaf = true
      entry({"admin", "status", "nameinfo"}, call("action_nameinfo")).leaf = true
    end
end

It is functional and working great though I am still finishing the up a couple last things, I hope to have it completed today, once I finish you can do a diff on it, I think it should merge much nicer then the original version.

(Last edited by hostle19 on 13 Jan 2016, 17:21)

Ok i have finished the new version, in my opinion its a much better approach. I have added measures to prevent empty main tabs as you mentioned in your post above. I also moved the package to applications and added more accurate and precise comments. I created a new fork of luci from today and added the commits to it. The new fork can be found here --> https://github.com/Hostle/luci.git

I think you'll find it is much cleaner and it should merge much better. There is still a few more things I would like to see before it is fully committed into luci  ...

1. a nicer interface for the "Edit Users" I was thinking of laying it out like the "Interfaces" pages where the current users are listed with buttons to edit or remove them.

2. the "luci.users" module needs to be optimized and better error checking implemented.

3. Perhaps deeper permission options for ssh privileges.

I am sure Jow and the others can whip this into shape pretty quick, I am back in schoool now but I will do my best to contribute what and when I can.

Thanks. I quickly browsed the new version, but didn't try to compile, yet.

A few observations: I think that you have copied files from CC15.05 to trunk Luci without noticing that the function calls have changed between CC and trunk. That will break things.

E.g. regarding "network" tab, you have undone https://github.com/Hostle/luci/commit/8 … ac78522926 in https://github.com/Hostle/luci/commit/e … 86868cac13 by erroneously changing the "post" back to "call".

I imported your new repo to my own luci repo at github and used editor & git to polish it a bit.
* I reverted the invalid call/post changes (CC15 vs. trunk code).
* I removed your additional indenting of menu items to minimize the change delta. (that makes the code a bit less clear to read, but makes it much more clear to see the changes at github now in discussion phase)
* I also removed unnecessary whitespace changes to avoid clutter of changes

The "polished" output is here:
https://github.com/hnyman/luci/commits/multi2

I have not yet tried to compile it, but will do that.

EDIT  in Feb 2016:
current update branch is "multi3"
https://github.com/hnyman/luci/commits/multi3

(Last edited by hnyman on 23 Feb 2016, 16:48)

yes, I stand corrected on all counts smile great work

I opened a disccussion about this at Luci github.
https://github.com/openwrt/luci/issues/623

If you want to try the multi-user code with your DD trunk build, you can easily add my Luci repo as a remote to your own git and then pull from "multi2" branch. I used these commands to import this to my own Openwrt build. (I also created a new branch "multiuser" at my local feed repo so that I easily push the changes aside and return to normal default Luci by "git checkout master"):

 cd feeds/luci
 git checkout -b multiuser
 git remote add hnyman https://github.com/hnyman/luci.git
 git pull hnyman multi2
 git log --oneline

The multi2 branch contains up-to-date Luci of 11 Jan 2016 for DD trunk + the multi-user commits.

(Last edited by hnyman on 14 Jan 2016, 19:32)

Perfect, thanks hynman