OpenWrt Forum Archive

Topic: LuCI run with standard user (not root)

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

Hello,

I would like to run LuCI with ordinary user (not root user). I read the documentation, but without success.
I add a new user with busybox adduser function but unfortunately I can't access with this user (no problem with root)
Does anybody make something like that ?
Thanks in advance for your answer.

ksin

Without some serious hacking, I think you're out of luck. OpenWrt and LuCI are pretty much designed to have all configuration modified by the root user.

This is a bit old, but here is the "serious hacking" that was required to add additional user support to the old web interface:

# cat /etc/httpd.conf
/:root:$p$root
/:admin:$p$root
/:myusername:$p$myusername
/:anotherusername:$p$anotherusername
.asp:text/html
.svg:image/svg+xml
.png:image/png
.gif:image/gif
.jpg:image/jpg
.js:application/x-javascript

All I had to do was add the third and fourth lines so that I could have two non-root users log in and have full control over the webif.

I don't have a working build with LuCI right now and I'm not entirely clear on what you want to do with it, but this may be a start.

DCRoss: tongue -- I thought he meant a different user in /etc/passwd, I swear

Yes Kupesoft, you are right,
I would like to add a new user but only for display and not modification.
Do you confirm it's a lot of work ?

Ksin

Does anyone have an update on this?  I am running luci on 8.09.  I can login with a non root user, but all I get is a white screen.  Any help?

jalbert wrote:

I can login with a non root user, but all I get is a white screen.

same here. If it is not working throuhg the /etc/passwd, maybe there is a way of just authenticating to the web-server (with an htpasswd-file or something like that).

I need an admin-user just for logging in to the luci webinterface. The Services can remain in running as root-user.... Does anyone have a clue how to realize this? I think changes need to be made in luci to get this working. Im running an older version of luci-0.9 (revision 6122)....

Beeing a configuration UI, LuCI is designed to run as root. Even if you allow another user to login he gains full root right through the ui and can for example just change the root password and take over the device.
Until LuCI gains acl management on a per-page basis there will be no true multiuser support.

Thanks for your answer jow. I think I need to be more conkrete on my issue:

We are delivering OpenWrt-based routers to our customers. When they run into trouble they give us a call and we are connecting to the box using ssh. Now we need the root-password to be able to login/configure their system. It happens to often that the customer who is calling, does not know the password. So we thought about using the root-user for remote maintenance, and creating an admin-user for our customers.

At the moment I added an admin-user in /etc/passwd which has the same uid and gid as root. Now Im able to login using admin and do all the stuff that root can do. This works fine for me, but Ive been told to switch these usernames. So I need to make admin the user for our customers to login (on LuCI), and root the user for remote access (ssh).

Can you tell me what needs to be done to login as admin on LuCI?

Monkey

Just put a public key for SSH into /etc/dropbear/authorized_keys and bake that into the image.

I'm also attempting to set up a multi user system. I would like to have the standard root user w/ ssh access and then either and admin or some sort of restricted access web UI interface for the other user login.

Everything seems to work okay if you setup the system w/ multi user via ssh. I can simply restrict access and control via the normal unix permission settings. But luci is a different beast, I tried to change the group w/ rw access on all the luci and lua files needed but i still get the blank white page on login w/ a non root user.

it is possible to webif2 X-wrt

Hello,

I submitted a patch to this forums to achieve the following:

- Disable 'root' login in the web interface, so that we make a distinction between system and web interface administration. SSH/telnet interface still functional for 'root' user, but not for 'webadmin' user.

- Allow a new user "webadmin" full control of the web interface

- Disable web interface access to any system user other than 'webadmin'. Currently, any system user is able to input user/password and get a blank page if that user is not 'root' (or whatever sysauth is set to).

See https://forum.openwrt.org/viewtopic.php … 52#p225552

(Last edited by nachoparker on 17 Feb 2014, 12:59)

Not necro this thread but I am working on a project that requires non root user access to the luci web ui as well. I am very close to working multi user hack for luci but i need a little help to finish it off

To allow multi user login (as root) is a very simple hack and requires one edit to the .. luci/dispatcher.lua file

function authenticator.htmlauth(validator, accs, default)
    local user = luci.http.formvalue("username")
    local pass = luci.http.formvalue("password")

    if user and validator(user, pass) then
        user = "root"  <---#### if user/pass check grant root access ####
        return user
    end

    require("luci.i18n")
    require("luci.template")
    context.path = {}
    luci.template.render("sysauth", {duser=default, fuser=user})
    return false

end

of course you need to add the users using a shell script or by copiling with adduser support.

Now to only 1 non root user is very simple aswell and requires 2 edits ...3 to prevent the user from setting root passwd from ui

1. edit the .. luci/controller/admin/index.lua as follows ...

function index()
    local root = node()
    if not root.target then
        root.target = alias("admin")
        root.index = true
    end    
    local page   = node("admin")
    page.target  = firstchild()
    page.title   = _("Administration")
    page.order   = 10
    page.sysauth =  "root"  <--#### change username ####
    page.sysauth_authenticator = "htmlauth"
    page.ucidata = true
    page.index = true

    -- Empty services menu to be populated by addons
    entry({"admin", "services"}, firstchild(), _("Services"), 40)
end

2. edit the  .. luci/controller/admin/servicectl.lua as follows ..

## and again change the "root"  to non root username ##

function index()
   entry({"servicectl"}, alias("servicectl", "status")).sysauth = "root" 
   entry({"servicectl", "status"}, call("action_status")).leaf = true
   entry({"servicectl", "restart"}, call("action_restart")).leaf = true
end

3. and to prevent the user from setting the root password from the ui you edit the .. luci/controller/admin/system.lua  and change the "root" in the set_passwd function to the non root username or add a conditon to only so if user is root .

you may also need to remove the /tmp/indexcache file from the changes to take effect ...if you were already loggeed in before making the cahnges.

I have tested this and it works 100% ... this allows a non root user to log in with non root users privileges. However since these variable are currently hard coded after making the changes only the non root user can log in, all other users receive the "CGI failed to produce response .." error. including root

So to complete this hack, these three variables must be set to the  username entered by the user at login ...if the user/pass checks out. I have tried using a function to provided the name enterd by the user to the locations needed but i seem to be having some problems with the plumbing lol

Hopefully Jow or someone with more knowledge of the luci system can help to allow setting these variables at login and complete the multi user hack for luci. One can easily add conditons using the username or user privi's to prevent non root users from accessing the parts of the web ui that allow them to set root passwds, firewall settings, network settings,  ssh settings...etc

(Last edited by hostle19 on 13 Apr 2014, 04:03)

ok so for a simple test, i had the htmlauth store the username provided by the username in the global table. Then tried to access it for the index sysauth vaule but it is not accesable to inside of index however it can be accessed from the from the page once it has loaded . So it would seem that index is parsed before the username is ever submited from the login ..??

just trying to get a grapse on what is going on here

What about a person who wants to login via ssh as a normal user. For instance I have tried to set this up but I had trouble doing this because the documentation that I was following requested me to create a user on the filesystem like so:

mkdir /home/user

That does not seem to work on my openwrt installation. I did not find any other documentation that would show me how else to do this.

users can be added very with a simple sh script.  Here is the one i use

USE AT YOUR OWN RISK !!

name: adduser

#!/bin/sh

## VARIABLES ##
login=$1
uid=$2

passwdf="/etc/passwd"
passwdfmin="/etc/passwd-"
shadowf="/etc/shadow"
shadowfmin="/etc/shadow-"
groupf="/etc/group"
homerootdir="/home"
shell="/bin/ash"

## START ##
echo "Add a new user:"
if [ "$1" != "" ] ; then
  login=$1
else
  echo -n "login: " ; read login
fi

username=`grep $login $passwdf|awk -F : '{print $1}'`
if [ "$username" = "$login" ]; then                               
  echo "ERROR: The user $login already exists, so please use a different login name."
  exit 1
else
  echo "using username: $login"
fi
          
if expr "$2" : '-\?[0-9]\+$' >/dev/null ; then
  uid=$2
else
  uid="$(awk -F: '{ if (big < $3 && $3 < 5000) big=$3 } END { print big + 1 }' $passwdf)"
  if [ $uid -lt 1000 ] ; then
    uid=1000
  fi
fi

userid=`grep $uid $passwdf|awk -F : '{print $1}'`
if [ "$userid" = "$uid" ]; then
  echo "ERROR: The userid $uid already exists, so please use a different userid."
  exit 1
else
  echo "using uid/guid: $uid"
fi
                              
homedir=$homerootdir/$login
                              
# gid=uid as in Fedora
gid=$uid

# echo ${login}:x:${uid}:${gid}:${fullname}:${homedir}:$shell >> $passwdf                      
echo ${login}:x:${uid}:${gid}:${login}:${homedir}:$shell >> $passwdf
echo ${login}:*:${uid}:${gid}:${login}:${homedir}:$shell >> $passwdfmin
echo ${login}:*:11647:0:99999:7::: >> $shadowf
echo ${login}:*:11647:0:99999:7::: >> $shadowfmin
echo "${login}:x:${gid}:$login" >> $groupf
                                
if [ ! -d "$homerootdir" ]; then
  mkdir  $homerootdir
fi

if [ ! -d "$homedir" ]; then
  mkdir $homedir
fi
                                    
#cp -R /etc/skel/.[a-zA-Z]* $homedir
chmod 755 $homedir
find $homedir -print | xargs chown ${login}:$login
passwd $login
                                    
exit 0

To set uid/guid you must supply it as second argument to the script..

usage: adduser <new username> <uid> 

ie ... adduser Frank 500

if no args are provided then you will be prompt to enter user name and uid/guid will automatically be set start at 1000 and incremented +1 per new user.

after runing the script you should be able to log on via ssh with the new user/pass combo.

##UPDATE ##

there was a error in the script above, {fullname} is no logger a variable as in is the same as {login} so it was redundant and I removed it but for got to replace it in the script. I have made the edit to the script, it should was as desired now

(Last edited by hostle19 on 16 Apr 2014, 17:07)

zopico wrote:

What about a person who wants to login via ssh as a normal user. For instance I have tried to set this up but I had trouble doing this because the documentation that I was following requested me to create a user on the filesystem like so:

mkdir /home/user

That does not seem to work on my openwrt installation. I did not find any other documentation that would show me how else to do this.

I should also point out the error in your syntax so you understand why the cmd you entered did not work.

you are correct when you say that openwrt does not contain the /home directory natively ( openwrt was designed as a single user system so there is only root user ...no need for home directory) how ever you can easily add it from the cmd line if you use the right syntax. The reason it would not work the way you entered it is ...

mkdir /home/user 

this is telling the shell to add the directory "user" to the "/home" directory, but there is no home directory ..yet

so you first need to create the "/home" directory before you can add the "user" directory to it

ie .. 

 mkdir /home 

then you can add the /user directory to it..

ie 

mkdir /home/user 

jsyn  smile

Is there any lua page can adduser?


hostle19 wrote:

users can be added very with a simple sh script.  Here is the one i use

USE AT YOUR OWN RISK !!


name: adduser

#!/bin/sh

## VARIABLES ##
login=$1
uid=$2

passwdf="/etc/passwd"
passwdfmin="/etc/passwd-"
shadowf="/etc/shadow"
shadowfmin="/etc/shadow-"
groupf="/etc/group"
homerootdir="/home"
shell="/bin/ash"

## START ##
echo "Add a new user:"
if [ "$1" != "" ] ; then
  login=$1
else
  echo -n "login: " ; read login
fi

username=`grep $login $passwdf|awk -F : '{print $1}'`
if [ "$username" = "$login" ]; then                               
  echo "ERROR: The user $login already exists, so please use a different login name."
  exit 1
else
  echo "using username: $login"
fi
          
if expr "$2" : '-\?[0-9]\+$' >/dev/null ; then
  uid=$2
else
  uid="$(awk -F: '{ if (big < $3 && $3 < 5000) big=$3 } END { print big + 1 }' $passwdf)"
  if [ $uid -lt 1000 ] ; then
    uid=1000
  fi
fi

userid=`grep $uid $passwdf|awk -F : '{print $1}'`
if [ "$userid" = "$uid" ]; then
  echo "ERROR: The userid $uid already exists, so please use a different userid."
  exit 1
else
  echo "using uid/guid: $uid"
fi
                              
homedir=$homerootdir/$login
                              
# gid=uid as in Fedora
gid=$uid

# echo ${login}:x:${uid}:${gid}:${fullname}:${homedir}:$shell >> $passwdf                      
echo ${login}:x:${uid}:${gid}:${login}:${homedir}:$shell >> $passwdf
echo ${login}:*:${uid}:${gid}:${login}:${homedir}:$shell >> $passwdfmin
echo ${login}:*:11647:0:99999:7::: >> $shadowf
echo ${login}:*:11647:0:99999:7::: >> $shadowfmin
echo "${login}:x:${gid}:$login" >> $groupf
                                
if [ ! -d "$homerootdir" ]; then
  mkdir  $homerootdir
fi

if [ ! -d "$homedir" ]; then
  mkdir $homedir
fi
                                    
#cp -R /etc/skel/.[a-zA-Z]* $homedir
chmod 755 $homedir
find $homedir -print | xargs chown ${login}:$login
passwd $login
                                    
exit 0

To set uid/guid you must supply it as second argument to the script..

usage: adduser <new username> <uid> 

ie ... adduser Frank 500

if no args are provided then you will be prompt to enter user name and uid/guid will automatically be set start at 1000 and incremented +1 per new user.

after runing the script you should be able to log on via ssh with the new user/pass combo.

##UPDATE ##

there was a error in the script above, {fullname} is no logger a variable as in is the same as {login} so it was redundant and I removed it but for got to replace it in the script. I have made the edit to the script, it should was as desired now

working on a full blown multi-user setup for openwrt, stay tuned as i am almost complete wink

That's awesome, as I would like for my roommates to be able to check the graphs, logs and firewall stats by themselves without giving them root access (and better yet the possibility to change the configuration at all) wink

I tried this hack with admin instead of root.

Add admin with : useradd -M -u 1000 -g 1000 -s /bin/false
Create ssh key for root and disable ssh password login
Modify files like here => https://forum.openwrt.org/viewtopic.php … 53#p230053

It works good. I can access luci inteface with admin user and ssh with root and ssh key.
In luci interface, login with root give me a blank page, so I have modified /usr/lib/lua/luci/sys.lua like this :

function user.checkpasswd(username, pass)                                     
        if username ~= "root" then                                                         
                local pwh, pwe = user.getpasswd(username)   
                if pwe then                             
                        return (pwh == nil or nixio.crypt(pass, pwh) == pwh)
                end                                                                 
        end                                                         
        return false                                           
end

Now, every username in luci other than admin return to luci interface.

(Last edited by fred3398 on 20 Jun 2015, 00:56)

The discussion might have continued from here.