Marking files as "Hidden / Inaccessible" on filesystem

Chris Johns chrisj at
Sat Mar 30 00:31:47 UTC 2019

On 30/3/19 2:22 am, Matthew J Fletcher wrote:
> Is there a method of hiding (does not appear in a 'ls -l' directory listing, or
> FTP listing) a file ?,. in addition is there a way of making a file inaccessible
> (cannot cat to screen from console, or ftp by guessing the name) ?
> The application of course would still need access via the C api.

The way I do this is a combination of users, groups, chroot, cmdchown and cmdchmod.


Create /etc/passwd and /etc/group files. Have a `root` entry and then entries
for the other levels of access you wish to provide.

You may need to have a default set up in code so you can create these files if
they do not exist. This is what I do as /etc is in the IMFS file system which is
created on each restart. This in turn may require you hold a copy in the
non-volatile media you copy to /etc on restart if you allow user accounts to be
created. Only store the encrypted keys.


Add an account home directory to a user's passwd entry that can be used as the
chroot base. You can then place files else where in the file system they cannot
see or access. Remember to add local copies of files parts of the system may
need, for example a chroot home directory of user `joe` could be `/homes/joe`,
and a copy of `passwd` as `/homes/joe/etc/passwd` is needed so `ls` can work.
You will need a copy as symlinks will not work.


Use `cmdchown` and `cmdchmod` to control user access to commands. You can
control the access to specific commands and so limit what a user can do.


Together these constructs give you tight control over the accounts and if you
provide support to manage the accounts you can control what can be done. A
`root` user can do anything and is typically used by the development team and
production. You can then create specific types of accounts and use groups to
manage them.

Lets have `root` as the engineering/development user with open access. We also
want an `oem` group and user a product partner can use to do extra things. This
may be controlling feature sets and end user can access. Then there are users,
and in this example we will have a single user account called `user` with a
simple and easy password `password`. The `user` account is given limited access
to the file system and commands.

The accounts are managed with these files:

 (note, the password hashes are junk)

[/] # cat /etc/passwd
[/] # cat /etc/group

I hope these files explain themselves.

Start a shell using the standard login handler RTEMS provides:

 void run_shell(bool have_login, rtems_task_priority priority)
   rtems_shell_login_check_t login = NULL;
   rtems_status_code         sc;

   if (have_login)
     login = rtems_shell_login_check;

   sc = rtems_shell_init ("sh",
                          20 * 1024,
                          "/dev/console", 0, 1, login);
   if (sc != RTEMS_SUCCESSFUL)
     fprintf (stderr,
              "shell: starting shell: %s (%d)",
              rtems_status_text (sc), sc);

The argument `have_login` can be set to `false` to disable the login. This can
be useful in development environments where developers are needing to login all
the time. A compile time or physical switch can be used to control this argument.

Use the `cmdls` command to see what commands are accessible by which users and
then use `cmdchown` and `cmdchmod` to control the access:

  (the list has been shorten)

[/] # cmdls
r-x------     0     0 help
r-xr-xr-x     0     0 alias
r-x------     0     0 time
r-x------     0     0 cmdls
r-x------     0     0 cmdchown
r-x------     0     0 cmdchmod
r-x------     0     0 joel
r-xr-xr-x     0     0 date
r-x------     0     0 echo
r-x------     0     0 edit
r-x------     0     0 sleep
r-x------     0     0 id
r-x------     0     0 tty
r-xr-xr-x     0     0 whoami
r-x------     0     0 logoff
r-x------     0     0 setenv
r-x------     0     0 getenv
r-x------     0     0 unsetenv
r-x------     0     0 cp
r-xr-xr-x     0     0 pwd
r-xr-xr-x     0     0 ls
r-x------     0     0 chdir
r-x------     0     0 mkdir
r-x------     0     0 rmdir
r-x------     0     0 chroot
r-x------     0     0 chmod
r-x------     0     0 cat
r-x------     0     0 mv
r-x------     0     0 rm
r-x------     0     0 ln
r-x------     0     0 dd
r-xr-xr-x     0     0 df
r-xr-xr-x     0     0 md5
r-xr-xr-x     0     0 shutdown
r-x------     0     0 cpuuse
r-x------     0     0 top
r-x------     0     0 wkspace
r-x------     0     0 malloc
r-x------     0     0 rtrace
r-xr-xr-x     0     0 ifconfig
r-xr-xr-x     0     0 route
r-xr-x---   100   100 oem-only-cmd
r-xr-xr-x     0     0 user-cmd

Here you can see commands only root can run:

 r-x------     0     0 chroot
 r-x------     0     0 chmod
 r-x------     0     0 cat

Commands all users can run are:

 r-xr-xr-x     0     0 date
 r-xr-xr-x     0     0 shutdown

A command only `root` and `oem` can run:

 r-xr-x---   100   100 oem-only-cmd

I like to add a function to execute a shell command and I use this to run the
`cmdchown` and `cmdchmod` commands during start up to set up the command perms.
These settings are not persistent across reboots. I have also had a `joel`
script on the non-volatile disk to do this and then run just that script. You
have a few options to select from here.

To further improve the user experience I suggest you create `/etc/issue` and
`/etc/` with something suitable. The file can support a few escape
controls that can be useful. I do not think they are documented but you can see
them in the code here ...


More information about the users mailing list