Puppy Linux Discussion Forum Forum Index Puppy Linux Discussion Forum
Puppy HOME page : puppylinux.com
"THE" alternative forum : puppylinux.info
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

The time now is Wed 26 Nov 2014, 21:38
All times are UTC - 4
 Forum index » House Training » HOWTO ( Solutions )
How to Build a Multiuser Puppy
Moderators: Flash, Ian, JohnMurga
Post_new_topic   Reply_to_topic View_previous_topic :: View_next_topic
Page 1 of 2 Posts_count   Goto page: 1, 2 Next
Author Message
Pizzasgood


Joined: 04 May 2005
Posts: 6270
Location: Knoxville, TN, USA

PostPosted: Sun 04 Oct 2009, 17:01    Post_subject:  How to Build a Multiuser Puppy
Sub_title: some assembly required
 

How To Make a Multiuser Puppy

This guide is based off the work I did to produce Multiuser Puppy, and the discussions we had here and here. I am assuming the reader is comfortable with Puppy's internals and with utilities such as grep, sed, and diff. I will reference the following files:

The following packages are also availible for use with shadow-4.1.4.2.pet, Linux-PAM-1.1.0.pet, and sudo-1.7.2p1.pet:





Misc. Small Changes
  • Create an empty directory '/home'.
  • Make /tmp 1777 (sticky and globally writable). The stickiness makes it so that if Alice creates the file /tmp/my_temporary_file, Bob can't modify that file unless Alice sets the permissions to let him. Otherwise he could move or delete the file, which could obviously be a pretty bad thing. The downside is that a user can spam /tmp with a bunch of files that other users might want to create...
  • Make /dev/zero and /dev/ptmx globally writable. The former is needed for a number of programs to run for some reason. The latter is needed by rxvt.
  • Make ddcprobe setuid. The scripts supporting X needed this.
  • Make /usr/X11R7/bin/Xvesa setuid.
  • IceWM's toolbar has some paths within ~/ but it can't handle variables. So I just trimmed off the /root/ part, making them relative. That seems to work. It may have problems if you start icewm from a location other than your home directory however.
  • Upgrade pcursorsel-0.1 to 0.2, which is multiuser-friendly (link)
  • Add a line in /usr/sbin/puppyinstaller that copies /home when it's setting up a full install.
  • The /usr/share/applications/file_sharing.desktop file had an Exec line like this:
    Code:
    Exec=rox -d /root/File-Sharing

    But that obviously won't do. I couldn't get it to work with variables either. So I changed it to this:
    Code:
    Exec=filesharedir

    and then added the script /usr/sbin/filesharedir with the following contents:
    Code:
    #!/bin/sh
    exec rox -d ${HOME}/File-Sharing





Xlock and box_splash (from pwidgets and ptray)

These use some GTK dialog stuff that had absolute paths into /root/. Changing them is pretty easy, but you have to be careful about the quotes. Here are the diffs:

/usr/local/apps/Xlock/AppRun:
Code:
- puppy-unleashed/packages/xlockmore-5.20.1patched/usr/local/apps/Xlock/AppRun -
index e7fc9b3..77f102c 100755
@@ -23,11 +23,11 @@ if [ "$PARAM1" = "-password" ];then
   <vbox>
    <text><label>"The first time Xlock runs, it will ask for a key, meaning a
 password. To change the password, you need to delete the
-file /root/.xlockrc, which is all that this button does..."</label>
+file '"${HOME}/.xlockrc"', which is all that this button does..."</label>
    </text>
    <button>
     <label>Click to clear password</label>
-    <action>rm -f /root/.xlockrc</action>
+    <action>rm -f ${HOME}/.xlockrc</action>
     <action>exit:PASSWD</action>
    </button>
   </vbox>
@@ -196,7 +196,7 @@ if [ ! "`echo "$PARAM1" | grep --extended-regexp "configure|inroot"`" = "" ];the
 fi
 
 
-if [ ! -f /root/.xlockrc ];then
+if [ ! -f ${HOME}/.xlockrc ];then
  XLOCKPARAMS="`cat /etc/xlockscreenparams`"
  rxvt -bg orange -g 36x1 -title "Create key (password)" -e xlock $XLOCKPARAMS
 else

/usr/local/pwidgets/box_splash:
Code:
---- puppy-unleashed/packages/pwidgets-2.0.8/usr/local/pwidgets/box_splash ----
index d6a57e8..ea4d39f 100755
@@ -5,10 +5,10 @@ export pwidgets_splash='
  <frame>
   <text><label>""</label></text>
   <text use-markup="true"><label>"<b>Pwidgets</b>"</label></text>
-  <text><input file>/root/.pwidgets/tmp/pwidgets-splashtext</input></text>
+  <text><input file>'"${HOME}/.pwidgets/tmp/pwidgets-splashtext"'</input></text>
   <progressbar>
    <label>Sigmund Berglund,   GPL 2008,2009</label>
-   <input>while [ "$I" != "100" ]; do I=`cat /root/.pwidgets/tmp/pwidgets-splash`; echo $I; usleep 500000; done</input>
+   <input>while [ "$I" != "100" ]; do I=`cat ${HOME}/.pwidgets/tmp/pwidgets-splash`; echo $I; usleep 500000; done</input>
    <action type="exit">Ready</action>
   </progressbar>
  </frame>

/usr/local/ptray/box_splash:
Code:
-------- puppy-unleashed/packages/ptray-0.5/usr/local/ptray/box_splash --------
index bbe07ac..171950b 100755
@@ -4,10 +4,10 @@ export ptray_splash='
 <vbox>
  <frame>
   <text><label>""</label></text>
-  <text><input file>/root/.ptray/tmp/ptray-splashtext</input></text>
+  <text><input file>'"${HOME}/.ptray/tmp/ptray-splashtext"'</input></text>
   <progressbar>
    <label>Sigmund Berglund,   GPL 2008,2009</label>
-   <input>while [ "$I" != "100" ]; do I=`cat /root/.ptray/tmp/ptray-splash`; echo $I; usleep 500000; done</input>
+   <input>while [ "$I" != "100" ]; do I=`cat ${HOME}/.ptray/tmp/ptray-splash`; echo $I; usleep 500000; done</input>
    <action type="exit">Ready</action>
   </progressbar>
  </frame>

If you haven't dealt with diffs before, don't worry. In case you haven't already figured it out, the original lines are the ones with a - in front, and the new ones are the ones with a +. That entire first column is extra, by the way. You'll note that the "<vbox>" tag is starting one space away from the edge. In reality it starts immediately on the edge.




Add more virtual terminals (optional, but makes life easier).

This one is pretty simple. You just have to edit /etc/inittab and add more lines, incrementing the tty numbers. For example, to go from two to six, you change:
Code:
::sysinit:/etc/rc.d/rc.sysinit
tty1::respawn:/sbin/getty -n -l /bin/autologinroot 38400 tty1
tty2::respawn:/sbin/getty 38400 tty2
::ctrlaltdel:/sbin/reboot

to
Code:
::sysinit:/etc/rc.d/rc.sysinit
tty1::respawn:/sbin/getty -n -l /bin/autologinroot 38400 tty1
tty2::respawn:/sbin/getty 38400 tty2
tty3::respawn:/sbin/getty 38400 tty3
tty4::respawn:/sbin/getty 38400 tty4
tty5::respawn:/sbin/getty 38400 tty5
tty6::respawn:/sbin/getty 38400 tty6
::ctrlaltdel:/sbin/reboot

Note: This will result in X running on VT 7 rather than VT 3.

If you have implemented toggleable autologin as described below, be sure to edit the /etc/inittab-AUTO and /etc/inittab-NOAUTO files too.




Set Puppy up to be able to optionally stop booting at a login prompt. (Included within user_utils-0.1.pet)

Make two copies of /etc/inittab, one named inittab-AUTO and one named inittab-NOAUTO. In the NOAUTO one, edit the tty1 line to look more like the others. As in, rather than
Code:
tty1::respawn:/sbin/getty -n -l /bin/autologinroot 38400 tty1

use
Code:
tty1::respawn:/sbin/getty 38400 tty1

Next, you just need to add a wizard to copy one or the other over inittab. I included such a wizard in the user_utils-0.1.pet package, named /usr/sbin/autologin-wizard.

You could also do this without the AUTO and NOAUTO versions by using sed to edit the tty1 line. However, if the user wanted to change the structure of the file, they'd have to modify the script too. This way they just have to modify the other two inittab-* files.




Proper user utilities such as useradd and gpasswd (shadow-4.1.4.2.pet)

Puppy includes limited versions of the real tools courtisy of Busybox. They don't have as many features and aren't as nice. So you'll need to replace them with the real thing. They are in a package called Shadow and I've provided a package above. I made a few changes from the default configuration, as follows:
Code:
./configure --build=i486-t2-linux-gnu --prefix=/

/etc/login.defs:
    Prevent it from telling the user he has no mail after every login.
      Change MAIL_CHECK_ENAB from yes to no

    Use md5 for the password hash, which removes the 8 char max limit.
      Add ENCRYPT_METHOD MD5

    Put /sbin and /usr/sbin into the PATH for limited users
      Change ENV_PATH from PATH=/bin:/usr/bin to PATH=/sbin:/bin:/usr/sbin:/usr/bin


Note that the following binaries should be SETUID (chmod u+s <filenames>) if the aren't already:
    /bin/su
    /bin/chage
    /bin/chfn
    /bin/chsh
    /bin/expiry
    /bin/gpasswd
    /bin/newgrp
    /bin/passwd


If you are using Unleashed, be sure you deal with any potential overlap from the busybox versions. I did this by duplicating the busybox package to create a new one with "-no_shadow_overlap" appended to the version number, and then removing the following files from it (and updating packages.txt appropriately to load this rather than the old busybox package):
    /bin/addgroup
    /bin/adduser
    /bin/delgroup
    /bin/deluser
    /bin/login
    /bin/su
    /usr/bin/passwd


You may want to go into the shadow package and add symlinks from useradd etc. to adduser. I didn't do this because it's easier for me to remember which versions of the utilities I'm working with if I have to use the real name.




/etc/skel

It's nice to have a template to create users' home directories from. That template is generally /etc/skel. When you use the useradd program with the -m option, it will automatically create the user's home directory and populate it from /etc/skel. But where is /etc/skel populated from? I'm a lazy person, so I decided to populate /etc/skel from /root, and to not bother being picky about only copying specific files. Of course, some things will need adjusting so that their paths work out right. Sometimes you'll have relative symlinks that point from /root/the_link to ../usr/bin/wherever_the_target_is. That link would no longer work if it started in /home/alice/. And sometimes a link named /root/link_name will be an absolute link pointing at /root/link_target, which wouldn't break when moved to /home/alice/, but it wouldn't help much either. And obviously, some files will have '/root/' specified in them. So, I wrote a script that will automatically take care of all that:
Code:
usage: populate_skel [-u|-c|-n|-e] [-s SOURCE_DIR ] [ -d DEST_DIR ]

This is a script to populate the /etc/skel directory from the
/root directory, which attempts to also correct any absolute
symlinks pointing into /root and any relative symlinks pointing
out of /root, so those would break during the move.  It also
uses sed to convert instances of "/root/" to "${HOME}/" in the
files copied.

 -u             Only copy newer files
 -c             Delete DEST_DIR before the copy
 -n             Do not attempt to correct symlinks
 -e             Do no change instances of "/root/" to "${HOME}/"
 -s SOURCE_DIR  Specify a different source than /root
 -d DEST_DIR    Specify a different destination than /etc/skel

This isn't perfect. Some files cannot handle a "${HOME}" inside them. And some files might be corrupted if you try using this (for example, you should generally delete any seamonkey profile that gets copied into /etc/skel with this).

The script is included in the user_utils-0.1.pet package.

I also modified my createpuppy script from Unleashed to run populate_skel. That way I don't need to mess with modifying all the packages to put things in /etc/skel. I just let them populate /root normally, then createpuppy will run populate_skel -n. I don't remember why I had it use the -n option, but I'm sure there was a good reason for that... I also added a line to clear out the mozilla profile after populate_skel finishes. Here is the diff:
Code:
diff --git a/puppy-unleashed/createpuppy b/puppy-unleashed/createpuppy
index 0b5d20b..d8429b2 100755
--- a/puppy-unleashed/createpuppy
+++ b/puppy-unleashed/createpuppy
@@ -17,6 +17,7 @@
 #v406 kernels/<sub dir> name can now be named <kern version>-<text>
 #v411 remove stray unipup scripts.
 #v412 add ssb.ko module to initrd (needed by ohci-hcd.ko).
+#vPP4 add option to create /etc/skel based on /root
 
 APATTERN='^".\+" ".\+" .\+ ".*" \\'
 ERRPKG="`cat packages.txt | grep -v "$APATTERN"`"
@@ -815,6 +816,19 @@ sync
 cp -f /tmp/PuppyPinfixed rootfs-complete/root/Choices/ROX-Filer/PuppyPin
 
 
+#To support multiuser, create /etc/skel from /root
+if [ -x rootfs-complete/usr/sbin/populate_skel ]; then
+ echo "Press ENTER to create /etc/skel from /root using 'populate_skel', or"
+ echo "any printable character and then ENTER to not create /etc/skel: "
+ read CREATE_SKEL
+ if [ "$CREATE_SKEL" = "" ]; then
+  rootfs-complete/usr/sbin/populate_skel -n -s rootfs-complete/root -d rootfs-complete/etc/skel
+  #the populate script seems to corrupt the mozilla profile, so clear that out
+  rm -r rootfs-complete/etc/skel/.mozilla
+  echo
+ fi
+fi
+
 echo -n "Press ENTER to build files that will be in the iso: "
 read yabbo
 echo


Some of the files that need to have a direct path rather than ${HOME} are ~/.gtkrc*, ~/.jwmrc*, and ~/.jwm/*. So for ~/.gtkrc* I added the following code in ~/.xinitrc:
Code:
#make sure the gtk files have the home directory rather than ${HOME}, as they can't handle that
for i in $HOME/.gtkrc*; do sed -i "s|\\\${HOME}|$HOME|g" "$i"; done

For the JWM files, I moved the jwm binary from /usr/X11R7/bin/jwm to /usr/X11R7/bin/jwm.bin, and then created /usr/X11R7/bin/jwm as a shell script containing the following:
Code:
#!/bin/sh
find "$HOME" -name '.jwm*' -type f -exec sed -i "s|\\\${HOME}|$HOME|g" "{}" \+
find "$HOME/.jwm" -type f -exec sed -i "s|\\\${HOME}|$HOME|g" "{}" \+
exec jwm.bin "$@"


Those changes are not included in the user_utils package.

During this guide I will often say that I did something in /etc/skel/ or ~/. Technically I did those things in /root and the populate_skel script propagated the changes into /etc/skel for me. Meaning that those changes also apply to /root, not only /etc/skel. Something to be aware of.




Configuring bashrc

A confusing point is that Bash doesn't support a global bashrc, but many sites refer to /etc/bashrc as being global. How it actually works is that you set up the default ~/.bashrc file to include the "global" /etc/bashrc file at the top. The user of course can edit his own .bashrc file if he wants, eliminating that inclusion. But this way if he leaves it and you later decide to change something in /etc/bashrc, all users who still include that from their .bashrc files will automatically inherit the changes. If you had instead just defined those defaults in the /etc/skel/.bashrc file, you would have to look though and maybe modify every user's .bashrc, which isn't desirable for many reasons (privacy, laziness, etc.)

So, in the /etc/skel/.bashrc file, you'll want to add something like this up near the top:
Code:
#source the global bashrc file
[ -f /etc/bashrc ] && . /etc/bashrc

As you can see, that code will be perfectly happy even if /etc/bashrc doesn't actually exist.

For Multiuser Puppy, I also removed the sourcing of /etc/profile from the /etc/skel/.bashrc file, so that the above is the only code actually being run (I did leave some commented out stuff).

As for what to put into /etc/bashrc, that would be things like aliases and what not. In a default Puppy, ~/.bashrc sources /etc/profile, but it mostly doesn't need to. The main thing you gain from that is the aliases defined there. Well, we can just move them out into /etc/bashrc.

The following is the contents of my /etc/bashrc:
Code:
#global bashrc file
#(actually, it must be sourced in each user's ~/.bashrc, but whatever)

#Allow limited users to set their timezone with the ~/Choices/localtime file
[ "$USER" != "root" ] && [ -e ${HOME}/Choices/localtime ] && export TZ=$(cat ${HOME}/Choices/localtime)

#use color in ls if o/p to a tty, not in a script...
alias ls='ls --color=auto'
#add some common ls aliases
alias ll='ls -l'
alias la='ls -a'
alias lA='ls -A'
alias lal='ls -al'

#v4.00 run e3vi whenever vi excuted...
alias vi=e3vi


I also removed the alias vi=e3vi and alias ls='ls --color=auto' lines from /etc/profile.

You may also want to add alias grep='grep --color=auto' to /etc/bashrc. I do that on my personal systems, but I left it out of this one because some people take offense to colored grepping. You'll note that I did add some ls aliases though. I figured they wouldn't bother anybody. And people can always override them in their ~/.bashrc file.

I'll explain the code about the timezone in the next section.

One last thing you should probably do is to create a symlink named /etc/skel/.profile pointed at .bashrc. I don't recall off the top of my head which one gets run under which circumstances, but this helps it remain more consistent if you log in under SSH.




Add sudo (Linux-PAM-1.1.0.pet, sudo-1.7.2p1.pet)

Sudo is useful in that you can use it to let individual users run specific commands with root privileges, without giving them the root password or letting them be able to run any arbitrary command as root (though if you make them a member of the "wheel" group, that does happen). Sudo depends on PAM support, so first you need to install Linux-PAM-1.1.0.pet. Then you can install sudo-1.7.2p1.pet. Sudo is configured by the files /etc/pam.d/sudo and /etc/sudoers. The former tells PAM what kinds of authentication need to happen for a user to use sudo. The file I included in the above package just requires the user to enter his password (not the root password). The latter file, /etc/sudoers, defines who is allowed to run what, along with some options for sudo. To edit it, use the visudo command. I created the "wheel" group and uncommented the option in /etc/sudoers that lets member of "wheel" run any command. I also set the default editor to be mp, but you can change it to geany or whatever you want by finding the line that looks like this:
Code:
Defaults editor=/usr/local/bin/mp
and changing it to this:
Code:
Defaults editor=/usr/bin/geany

I'm not going to get into how to configure sudo. I will mention however that in general, it's better to explicitely allow a user to run a limited selection of programs with it, rather than placing the user into the 'wheel' group so that he can run anything.

Note that /usr/bin/sudo must be setuid, and /etc/sudoers must be chmod 0440.

The sources for these packages are here: Linux-PAM, Sudo.




Let users use the GUI timezone wizard to set their timezone

Anybody can set their timezone simply be specifying the TZ variable in ~/.bashrc. But to make things more GUI-friendly, you can modify the /usr/sbing/timezone-set script to detect if the user is not root, and if so, create a file named ~/Choices/localtime that contains the timezone (the path to the file in /usr/share/zoneinfo for the timezone in question). An example timezone-set script is provided in timezone-set.tar.gz.
Next add a couple lines in /etc/bashrc to check for the existance of that file, and if found set the TZ variable accordingly. The lines to add to /etc/bashrc are these:
Code:
#Allow limited users to set their timezone with the ~/Choices/localtime file
[ "$USER" != "root" ] && [ -e ${HOME}/Choices/localtime ] && export TZ=$(cat ${HOME}/Choices/localtime)

As you can see, tihs doesn't allow root to use this system. The root user will get and set the system's default time. This is for consistency with the stock Puppy.

Note: That code is also shown up above in the bashrc section, so don't add it twice...




Making the Prompt More Informative

Some people like long prompts that tell them the date and their location in the filesystem and who they are and whether it's sunny out and all kinds of other nonsense. I'm not going to get into all that. Since I'm trying to make this essentially look and work like a stock Puppy with minimal changes to become multiuser friendly, I opted to only make a very small change to the prompt. The prompt is controlled by the PS1 variable, which is set in /etc/profile. I changed it from being a hardcoded # to using \$, which causes it to show # only when you are root, otherwise it shows a $:
Code:
PS1='\$ '

Note: Stock Puppy quotes the prompt with normal double-quotes. If you want to use \$, you must use single quotes. Otherwise you have to add one or two extra backslashes to get everything properly escaped.

It's also possible to set the prompt to be a different color. I generally set mine to be red if I'm root, and yellow or green otherwise. It's easier to distinguish the difference in color than the difference between # and $, IMHO. Also, it makes the prompt stand out from the rest of the text better, and generally just looks nicer. Again, because I'm trying to keep things as close to stock as possible, I did not do that here.

If you're interested in making things fancy, read this.




Mounting (mount-stuff.tar.gz)

If you do nothing, only root will be able to mount drives. Depending on how you want to use Puppy, that may be the desired behavior. For most desktop users however, it is not. They'll want to be able to mount their USB drives and what-not without su-ing to root. But opening the system to let any user mount is a Bad Idea, as some server programs will run as their own limited user to minimize the damage should they be compromised. So, what to do? This is where the concept of "groups" kicks in. You can set the "group" option in /etc/fstab for a partition, and then any member of the group that owns the partition will be able to mount it. So first things first: add a "disk" group:
Code:
groupadd disk

Then, you need to chgrp disk all the device nodes in /dev that correspond to drives. /dev/fd*, /dev/s[dr]*, /dev/hd*, and probably some others. There's a good possibility of missing some, but you don't need to worry about that as I'll mention shortly.

Next there needs to be an entry in /etc/fstab for every partition. That's where things get ugly. The sysadmin could of course add them manually, but that's a pain, and doesn't account for when Bob plugs in his USB drive. So, I wrote some scripts that latch into either Barry's "pup_event" system or udev, whichever is being used, and run another script (/sbin/pup_event_backend_fstab) when a new drive is detected. pup_event_backend_fstab then adds an entry to /etc/fstab. Since pup_event and udev run as root, the script will have enough permission to do this. While it's at it, it also makes sure that the device file belongs to the disk group. And to take care of any drives that are already connected on boot, I added some code to /etc/rc.d/rc.sysinit to run pup_event_backend_fstab on the existing drives too. Since in some situations a drive may have a different partition type than the last time it was used (two different USB drives for example) I made sure it's capible of editing lines. I also set it up so that if you manually change an fstab entry to remove the "group" option, the script will not touch that entry anymore. In case you want to have a root-only drive.

The partitions need to be mounted with mount-FULL, not the busybox mount, so I added some code to the mount script that takes care of this automatically, so the user can still use plain old "mount". Also, since a limited user cannot supply his own options, I added some lines to have it detect when just passing the raw commandline to mount-FULL fails and try to send it only the mountpoint. That allows things like Pmount to work with for limited users without actually being modified itself.

For the desktop icons to be updated, I needed to adjust /etc/rc.d/functions4puppy4, /sbin/pup_event_frontend_d, and /sbin/clean_desk_icons to be multiuser friendly. I didn't make pup_event_frontend_d completely multiuser friendly - it has functions involving saving USB installs and such that need to be done as root. But it's good enough to set up the desktop icons.

The modified files are availible in the mount-stuff.tar.gz file.

One catch is that NTFS partitions require mounting with ntfs-3g, but that doesn't work properly with the "group" option in /etc/fstab, and I couldn't get it to be user-friendly. So I added an extra option to the umount-client and umount-daemon (described below) to allow a limited user who is a member of the group owning the device node to tell the daemon to mount the partition (the daemon runs as root). The mount script has been modified to handle this automatically.

So, that takes care of mounting for any user who is a member of the 'disk' group.




Unmounting (mount-stuff.tar.gz)

If you set up mounting as described above, all seems fine and dandy. Until you try to unmount the partition. The "group" option doesn't let users unmount a partition. Probably because there's a chance that another user is now poking around in the partition. Anyway, we want to be able to unmount things so we can remove our USB drives.

So, I wrote /etc/init.d/umount-daemon, which runs as root and monitors /tmp/.umount-requests/. To unmount a partition, I added some code to the umount script that will call the /bin/umount-client script I wrote. umount-client will create a file in /tmp/.umount-request/ with a random name and which contains the path to the mountpoint of the partition. umount-daemon will detect the creation of the file, read the contents, determine if the user is authorized to unmount the partition (check that the group option is set in fstab and that the user and device node have the same group), unmount the partition, and delete the file umount-client created. Then umount-client will return you to the prompt. As mentioned above, it also can be used to mount partitions as root when you are actually a limited user, but that feature is strongly discrouaged. It is only included for rare situations where a limited user simply cannot mount the partition properly, such as with NTFS partitions.

The files needed are included in the mount-stuff.tar.gz file along with the ones for mounting.

So, the user should now be able to mount and unmount his drives with the normal mount and unmount commands, pmount, and the desktop icons. And since they'll all have proper /etc/fstab entries, you can even go into /mnt/ and click the mountpoints to mount them (ROX-Filer handles this automatically).




Audio

Initially, some audio devices in Puppy are globally usable, and some are not. This is not very nice. So, what you can do is make them all 660, and then set their group to "audio" (after creating the audio group of course...). Then, any user who belongs to the audio group can use the audio devices. I used the following commands:
Code:
#create the audio group
groupadd audio
cd /
#have the "audio" group own the audio devices
chgrp audio ./dev/snd/* ./dev/audio ./dev/admmidi ./dev/adsp ./dev/aloadC0 ./dev/amidi ./dev/amixer ./dev/audio ./dev/audio0 ./dev/dmmidi ./dev/dsp ./dev/midi ./dev/mixer ./dev/music ./dev/seq ./dev/sequencer ./dev/sequencer2 ./dev/sndstat ./dev/speaker
#make sure only authorized users can do audio things
chmod 660 ./dev/snd/* ./dev/audio ./dev/admmidi ./dev/adsp ./dev/aloadC0 ./dev/amidi ./dev/amixer ./dev/audio ./dev/audio0 ./dev/dmmidi ./dev/dsp ./dev/midi ./dev/mixer ./dev/music ./dev/seq ./dev/sequencer ./dev/sequencer2 ./dev/sndstat ./dev/speaker





Poweroff and Reboot (power-stuff.tar.gz)

In the stock Puppy, a limited user cannot poweroff or reboot the machine. As with mounting and audio, this may or may not be desireable. Thus, the solution is to add a "power" group and put people who should be able to do such actions into it. Then chmod 750 the poweroff and reboot commands. That's enough to limit who can run the commands to the right people, but it still doesn't grant them the permission to actually do the deed. So I wrote a daemon named /etc/init.d/power-daemon, which is very similar to the umount-daemon. It monitors /tmp/.power-requests/ for files containing "poweroff" or "reboot". The /tmp/.power-requests/ directory has it's permissions set to 770 and is owned by the power group, so only authorized users can create such files. The actual file creation is handled by the poweroff and reboot scripts. When run by non-root users, they create a file with the appropriate contents in /tmp/.power-requests/, which then runs the command again as root. When they are run as root, they skip the /tmp/.power-requests stuff and do what they normally do - run /etc/rc.d/rc.shutdown and then poweroff or reboot the computer.




Adding Users (included in user_utils-0.1.pet)

To avoid the need to remember all these groups when creating a new user, I wrote the /usr/sbin/adduser-wizard script. It gives you a GUI way to createa user, select whether he should be a part of the disk, audio, power, and wheel groups, and lets you set his password. It also uses the -m option when running useradd, so that the user gets his home directory created as well. After the home directory is created, it goes ahead and chmods it to 750 to keep it private. Finally, it goes ahead and adds the /etc/X11/$USER/ directory and sets the ownership to the new user. This wizard is a part of the user_utils-0.1.pet package I made.




Changing the Password (included in user_utils-0.1.pet)

I tried to make a gui for setting your password, but passwd doesn't have a way to accept a password from STDIN or environment variables. There is a program included in shadow called chpasswd that lets you do this, but it only works for root (that's the method I used for the adduser-wizard). I could do it with an "expect" script, but that would mean adding another dependency... So instead, I just wrote a script that pops up an rxvt window and runs the passwd command inside it. This way it can at least be run from the menu. I named it passwd-wizard and included it in the user_utils-0.1.pet.




Pwidgets background

Pwidgets was storing the background in /usr/share/backgrounds/Pwidgets_background, which is root only. So you can get around that by editing /usr/local/pwidgets/func and /usr/sbin/fixwidgets to store it at $HOME/.pwidgets/Pwidgets_background instead. That's in addition to replacing instances of /root/ with $HOME of course.




PetGet

Installing software is something that must be done as root. So added a couple lines near the top to throw an error message if you are not root:
Code:
#Don't bother attempting to run unless root
if [ "$(whoami)" != "root" ]; then
 [ "$(ps -eo comm | grep ^X)" = "X" ] && Xdialog -title "PETget package manager" --msgbox "Sorry, but only the root user\nhas permission to run petget" 0 0
 echo "ERROR: Must be root to run petget" >&2
 exit 1
fi





Fixmenus

This can be made mostly multiuser friendly with just a couple changes to convert /root into ${HOME}
Code:
diff --git a/puppy-unleashed/packages/xdg_puppy-0.7.6-5_4.2/usr/sbin/fixmenus b/puppy-unleashed/packages/xdg_puppy-0.7.6-5_4.2/usr/sbin/fixmenus
index 2dde04b..5eb8038 100755
--- a/puppy-unleashed/packages/xdg_puppy-0.7.6-5_4.2/usr/sbin/fixmenus
+++ b/puppy-unleashed/packages/xdg_puppy-0.7.6-5_4.2/usr/sbin/fixmenus
@@ -7,6 +7,8 @@
 #...the '_' will be converted to a '/', so the generated JWM config file is:
 # /root/.jwmrc
 # 5jan2008: fbpanel,lxpanel support developed by plinej.
+#06Sept2009 PG: Don't bother attempting to run unless root
+#31Oct2009 PG: Allow running as non-root
 
 
 #Puppy 2.14: XDG menu
@@ -15,7 +17,7 @@ TEMPLATES="`ls -1 /etc/xdg/templates | tr '\n' ' '`"
 for ONETPL in $TEMPLATES
 do
  [ "$ONETPL" = "README.txt" ] && continue
- ONEDEST="`echo -n "$ONETPL" | sed -e 's/_/\//g'`"
+ ONEDEST="`echo -n "$ONETPL" | sed -e 's|_|/|g' -e "s|^/root/|$HOME/|"`"
  ONESRC="/etc/xdg/templates/$ONETPL"
  echo "Generating $ONEDEST..."
 
@@ -24,6 +26,7 @@ do
  cat $ONESRC |
  while read ONELINE
  do
+  ONELINE="`echo -n "$ONELINE" | sed "s%\([='\\\"> ]\+\)/root/%\1$HOME/%g"`"
   EXECMENU="`echo -n "$ONELINE" | grep -o 'PUPPYMENU.*' | cut -f 2-5 -d ' '`"
   if [ "$EXECMENU" = "" ];then
    echo "$ONELINE" >> $ONEDEST

This won't let limited users define their own .desktop files or define their own templates (unless Puppy's XDG system already has support for that and I just don't realize it), but it will let them update their menu entries to match the .desktop files in /usr/share/applications, in case they get out of sync.




The X Windows System (x-stuff.tar.gz)

Beside the following changes, this also needed the permissions of /dev/zero changed, and ddcprobe and Xvesa setuid as described above.

~/.xinitrc
    Change all instances of /root/ into $HOME/
    Use ~/Choices/windowmanager rather than /etc/windowmanager

[list]Use /tmp/${USER}-<filename> rather than /tmp/<filename> for temporary files.
/usr/sbin/chooselocale
    Use ~/Choices/windowmanager rather than /etc/windowmanager

/usr/sbin/input-wizard
    If the user is not root, use /etc/X11/$USER/xorg.conf rather than /etc/X11/xorg.conf.

/usr/sbin/delayedrun
    Use ${HOME}/Choices/videomode rather than /etc/videomode

/usr/sbin/framebufferwizard
    Use ${HOME}/Choices/videomode rather than /etc/videomode

/usr/sbin/video-wizard
    Use /tmp/${USER}-<filename> rather than /tmp/<filename> for temporary files.
    Use ${HOME}/Choices/videomode rather than /etc/videomode

/usr/sbin/xorgwizard (note - xorgwizard doesn't actually work yet for limited users)
    Change all instances of /root/ into $HOME/
    Use ~/Choices/windowmanager rather than /etc/windowmanager
    Use /tmp/${USER}-<filename> rather than /tmp/<filename> for temporary files.
    If the user is not root, use /etc/X11/$USER/xorg.conf rather than /etc/X11/xorg.conf
    Use ${HOME}/Choices/videomode rather than /etc/videomode

/etc/windowmanager
    Moved to ~/Choices/windowmanager

/usr/X11R7/bin/restartwm
    Use ~/Choices/windowmanager rather than /etc/windowmanager
    Use /tmp/${USER}-<filename> rather than /tmp/<filename> for temporary files.

/usr/X11R7/bin/wmpoweroff
    Use /tmp/${USER}-<filename> rather than /tmp/<filename> for temporary files.

/usr/X11R7/bin/wmreboot
    Use /tmp/${USER}-<filename> rather than /tmp/<filename> for temporary files.

/usr/X11R7/bin/xwin
    Change all instances of /root/ into $HOME/
    Use /tmp/XLOADED instead of /etc/.XLOADED
    Make /tmp/XLOADED world-writable (rather than doing it per-user, because you don't want Alice starting X if Bob is already running it!)
    Use /tmp/${USER}-<filename> rather than /tmp/<filename> for temporary files.
    Use ${HOME}/Choices/windowmanager rather than /etc/windowmanager
    Use /etc/X11/$USER/xorg.conf if it exists, otherwise use /etc/X11/xorg.conf as usual.
    Use ${HOME}/Choices/videomode rather than /etc/videomode

The final forms of those are all availible in the x-stuff.tar.gz package.

Also modified /usr/bin/seahaven-multi to use ${HOME}/Choices/videomode, and the following files in the icewm and jwm packages to support using ~/Choices/windowmanager rather than /etc/windowmanager:
    pinstall
    /root/.icewm/startup
    /usr/bin/icewm2jwm
    /usr/bin/jwm2icewm

I did not include the modified files for icewm and jwm in the x-stuff.tar.gz package. Pull them out of the ISO if you need them.




Grep and Sed Work

Finally, I did some grep and sed work on a large number of files. The sed command itself was this:
Code:
sed -i 's|/root/|${HOME}/|' <FILENAME>

I don't remember exactly how I came up with the list of files that I used it on, but I believe I first ran a command like this in the packages/ directory of my unleashed tree to locate all packages that had files with '/root/' in them:
Code:
grep -lIR '/root/' * 2>/dev/null | cut -f 1 -d '/' | sort -u > /tmp/list

Then I think I skimmed through the list and culled out packages that I didn't want it to mess with (they seemed like blatenly root-only things, or too nasty to deal with any way but by hand). Then I ran something like this on a couple packages at a time:
Code:
grep --color -IR '/root/' package_1 package_2 package_3

That let me see exactly which parts of which files were involved. If they looked safe to be run through sed I would do something like this:
Code:
find package_1 package_2 package_3 -type f -exec sed -i 's|/root/|${HOME}/|'

The ones that didn't look fine I did by hand.

Since there were so friggin' many, I didn't do a good job of documenting them. Sorry. However, all of the work I've done on this project was done through Git, so I can provide the diff from that commit. That could be perused by and applied by hand, or if you have things laid out the same as my unleashed tree was it could be fed into the patch program. You could probably also feed it through patch without unleashed and just have patch strip off the first three components of the path. I'm not sure how well that would work though because there may be some duplication due to multiple versions of some packages. Anyway, here is the diff file: makestuffuserfriendly.diff




Git (for masochists who want to see exactly what I did)

I used Git when working on Multiuser Puppy. Git isn't for everybody, especially when working on large binary projects such as a Puppy derivatives. Because Git was primarily designed for dealing with source code, not large binary projects, there are a number of pitfalls a person desiring to use it for Puppy development should be aware of. I already wrote a lot of information on the subject when we were considering moving official Puppy development into a Git repository. That information now lives here: (link). You don't need to use Git. But you are free to clone my tree if you want to play around with exactly the build environment I used when creating Multiuser Puppy. My Multiuser Puppy work is under the "multiuser" branch.
git://pizzasgood.no-ip.org/puppy




Conclusion

That sums up what I did to make Multiuser Puppy work. Feel free to ask questions, suggest improvements, and point out gaping security holes I left open. A brief warning: I have no intention to maintain this. My goal was only to forge the path to make a multiuser Puppy possible. I've succeeded in that goal. So I'm moving on to other projects. I will of course still answer any questions and what-not, and maybe address any major problems. But it's up to "you" to reapply this to newer/older versions of Puppy where needed. They shouldn't be different enough to make a huge difference.


Last updated 2009-10-31

_________________
Between depriving a man of one hour from his life and depriving him of his life there exists only a difference of degree. --Muad'Dib


Edited_times_total
Back to top
View user's profile Send_private_message Visit_website 
Nathan F


Joined: 08 Jun 2005
Posts: 1760
Location: Wadsworth, OH (occasionally home)

PostPosted: Wed 28 Oct 2009, 13:53    Post_subject:  

Hi Pizzasgood. I just wanted to offer some of my old code if you're going to continue working in this vein.
Code:
svn checkout http://grafpup-linux.googlecode.com/svn/trunk/ grafpup-linux-read-only

I had a pretty nice user manager gui which put all the basic tasks in one place. Written in gtkdialog, of course. There were also a lot of Puppy programs which I painstakingly went through to make more multi-user friendly. Take whatever looks good to you. I think a lot of it used the same or similar solutions as yours (which from what I've read sounds very elegant) so hopefully it wouldn't be hard to adjust to your scheme.

One suggestion I would make is to add gksu along with the other utilities you've added. If you go for an older version it can be compiled without a lot of gnome libs and makes it so that if a normal user tries to start up a privileged program they can authenticate as root. I had it working pretty well at one time.

If none of it is useful or you just go your own way that's fine, too. Either way good luck with getting this concept accepted hereabouts.

Nathan

_________________
Bring on the locusts ...
Back to top
View user's profile Send_private_message AIM YIM MSNM 
Pizzasgood


Joined: 04 May 2005
Posts: 6270
Location: Knoxville, TN, USA

PostPosted: Thu 29 Oct 2009, 20:18    Post_subject:  

Cool. I'll take a look this weekend or so.
_________________
Between depriving a man of one hour from his life and depriving him of his life there exists only a difference of degree. --Muad'Dib

Back to top
View user's profile Send_private_message Visit_website 
zigbert


Joined: 29 Mar 2006
Posts: 5788
Location: Valåmoen, Norway

PostPosted: Fri 06 Nov 2009, 17:47    Post_subject:  

Pizzasgood
You show extreme qualities!

I will deal with the Pwidgets issues for the next Pwidgets release.


Sigmund

_________________
Stardust resources
Back to top
View user's profile Send_private_message Visit_website 
pri


Joined: 09 Oct 2009
Posts: 330
Location: Bandung Indonesia

PostPosted: Fri 26 Mar 2010, 02:30    Post_subject:  

hey pizzagood

hey there is a single pet to make it mulsti user Very Happy, i want make it for 4.3.1 i am work on it Very Happy

_________________
Learning by Doing
Back to top
View user's profile Send_private_message Visit_website YIM 
Pizzasgood


Joined: 04 May 2005
Posts: 6270
Location: Knoxville, TN, USA

PostPosted: Fri 26 Mar 2010, 03:46    Post_subject:  

No, there isn't. Sorry.

Good luck with 4.3.1. That would be pretty cool. Smile

_________________
Between depriving a man of one hour from his life and depriving him of his life there exists only a difference of degree. --Muad'Dib

Back to top
View user's profile Send_private_message Visit_website 
pri


Joined: 09 Oct 2009
Posts: 330
Location: Bandung Indonesia

PostPosted: Fri 26 Mar 2010, 11:54    Post_subject:  

its okey Very Happy

but how to make it login automaticaly as user not as root ? if multiuser is actif, it will be ask login and password everytime loged in.

_________________
Learning by Doing
Back to top
View user's profile Send_private_message Visit_website YIM 
pri


Joined: 09 Oct 2009
Posts: 330
Location: Bandung Indonesia

PostPosted: Sat 27 Mar 2010, 13:50    Post_subject:  

look like not working for 4.3.1 Sad error in useradd command

must find the other way to make it multi user, not willy multi user i think if use puppy, but mybe automatic login as other than root (as user for me) and let it using root directory or whatever, i dont know Very Happy

_________________
Learning by Doing
Back to top
View user's profile Send_private_message Visit_website YIM 
Pizzasgood


Joined: 04 May 2005
Posts: 6270
Location: Knoxville, TN, USA

PostPosted: Sat 27 Mar 2010, 15:24    Post_subject:  

Hmmm.... 4.3.x is a bit newer than 4.2, so the binary .pets might now work. If that's the case, you would have to recompile them on 4.3.1. Or it might be that 4.3.1 doesn't have one of their dependencies that 4.2.1 did have.

For automatically logging in, the way Puppy does that for "root" is with the "autologinroot" program, which is run from /etc/inittab.

If that program can log you in as root, then it should definitely be possible to make a program that will log you in as a user.

Doing a quick search, I found the source code from autologinroot:
http://www.murga-linux.com/puppy/viewtopic.php?t=5991
Code:
/*BK auto login */

int main() {
 execlp("login","login","-f","root",0);
}


So it looks like you could maybe change the "root" parameter to whatever user you want. Then you compile it with gcc -o autologinuser autologinroot.c and it will give you a "autologinuser" executable that will log in as whichever user you hardcoded into it. (I would name it "autologin<user>", replacing <user> with the name - so in my case I'd have autologinpizzasgood).

Then you can stick that in /bin/ and edit /etc/inittab to use it instead of autologinroot.

I don't know if that will work, but it might.


Also, instead of hardcoding the user, you could do this:
Code:
#include<unistd.h>
int main(int argc, char *argv[]) {
    if (argc != 2){
        execlp("login","login","-f","root",0);
    } else {
        execlp("login","login","-f",argv[1],0);
    }
}

Then it will login as root by default, but if you run it like "autologinuser bob", it would log in as bob. The only catch is I'm not sure how/if you can add that to inittab to pass the parameter (maybe just put the whole thing in quotes). You might have to play around with it to get that version to work.

But I would start with the hardcoded one, just to make sure that the concept works, and only then try the fancier version.

_________________
Between depriving a man of one hour from his life and depriving him of his life there exists only a difference of degree. --Muad'Dib

Back to top
View user's profile Send_private_message Visit_website 
pri


Joined: 09 Oct 2009
Posts: 330
Location: Bandung Indonesia

PostPosted: Sun 28 Mar 2010, 21:19    Post_subject:  

hello again pizzasgood

now iam was in user mode, but not using user user_utils-0.1.pet but using xonemoreuser-en.tar.gz. like a said before, look like command on user_utils-01.pet not same, i think the command now no longger useradd, but adduser.

xonemoreuser-en.tar.gz. , igot from this : http://www.murga-linux.com/puppy/viewtopic.php?t=15839&start=60

and i am make a autologinuser and work perfect. every login now iam on user mode. but now i cant go back to root mode to set anything again, when trying logout or exit, there is error said must be suid properly to using logout.

and my question is :
1. how to make i can logout to using root or can command as root to modify user area.
2. i cant using pmount, pmount just work only for sda else /mnt/home. and all sdb and other. (sdc, etc) how to enabke it ?
3. some icon on desktop was missing his icon picture. how it can be happen ?

...................................................

and i was trying to using my idea, login as user but still using /root directory. i think this is the best choise to puppy for me. but i cant using anything to work Very Happy look like puppypc locked /root directory and not permited using it. how to make it enable ? chmod it to some code ? or anything else Very Happy.

to add a user to use /root directory is use command :
adduser -h /root user

.....................................................

_________________
Learning by Doing
Back to top
View user's profile Send_private_message Visit_website YIM 
Pizzasgood


Joined: 04 May 2005
Posts: 6270
Location: Knoxville, TN, USA

PostPosted: Tue 30 Mar 2010, 23:54    Post_subject:  

"useradd" only exists if you install the shadow package. Puppy comes with adduser, which is similar, but not as powerful.

To temporarily become root, you can use the su command. It will ask you for the root password, and then you'll have root's permissions in that terminal session until you run "exit" or press CTRL-D, which will return you to your original user permissions.



For logout, it sounds like you might have to run this (as root or via 'su'):
Code:
chmod +s /bin/logout

That is the command to make a program setuid, which means the program will run with the ID of its owner no matter who runs it. In this case, root owns it, so the logout program will run with root privileges.

But you probably have /bin/logout as a symlink to busybox, and it's probably not good to have busybox be setuid.

I don't remember if I tried using logout in Multiuser Puppy 4.2.1. I think I did. But I installed "shadow", which added its own login program. I don't know if that's relevant.



Mounting is something that normally needs to be done as root. I wrote an elaborate daemon/client system that lets you trigger a mount as a user. A simpler way to do it would be with sudo. You could probably install sudo and then give the users who need to be able to mount a rule in sudo that lets them run pmount. (Sudo lets you specify users who can do anything through sudo, but you can also make them more restricted so that they can only run certain commands.) Then they could run "sudo pmount" and use that to mount things. You could probably make a script that adds the sudo for them.



To let a single user (I will name him "bob") live in /root, you could do this:
Code:
chown -R bob /root

But if you want to let multiple users use it, you would have problems. Each user would create files under his own ownership. You could play with the UMASK to maybe help, but it would probably be a losing battle. If you want more than one user you should probably let each user have his own home directory.

Also, even if only a single user is involved, if he logs in as root and does stuff, some of the files in /root might get set to being owned by root again.

Also, it's potentially dangerous to let a user modify things in /root, because then they could add scripts to /root/Startup or /root/.bashrc that would run when root logs in, with root's privileges.



I'm not sure what's wrong with your icons. Maybe something in xonemoreuser is out of date. I've never used that.

_________________
Between depriving a man of one hour from his life and depriving him of his life there exists only a difference of degree. --Muad'Dib

Back to top
View user's profile Send_private_message Visit_website 
pri


Joined: 09 Oct 2009
Posts: 330
Location: Bandung Indonesia

PostPosted: Wed 31 Mar 2010, 12:43    Post_subject:  

i am already using all pet on the fisrt post. but useradd have other problem. this is screnshot.
aduser.png
 Description   
 Filesize   10.52 KB
 Viewed   8451 Time(s)

aduser.png


_________________
Learning by Doing
Back to top
View user's profile Send_private_message Visit_website YIM 
Pizzasgood


Joined: 04 May 2005
Posts: 6270
Location: Knoxville, TN, USA

PostPosted: Sun 04 Apr 2010, 21:00    Post_subject:  

Do you have the appropriate groups? You may need to run these:
Code:
groupadd --system audio
groupadd --system drive
groupadd --system power
groupadd --system wheel

_________________
Between depriving a man of one hour from his life and depriving him of his life there exists only a difference of degree. --Muad'Dib

Back to top
View user's profile Send_private_message Visit_website 
Max Headroom


Joined: 28 Jun 2006
Posts: 187
Location: GodZone Kiwi

PostPosted: Fri 28 May 2010, 17:46    Post_subject: Pizzasgood Could U Please Advise the Relevance of these
Sub_title: Pizzasgood Could U Please Advise the Relevance of these
 

Pizzasgood Could U Please Advise the Relevance of these instructions w/ Grays NOP 4.3.1 w/ XFCE, I'd Hate 2 Start this then come up 2 a Brick wall that I can't Konquer! Smile Thanx Smile
Back to top
View user's profile Send_private_message YIM 
Pizzasgood


Joined: 04 May 2005
Posts: 6270
Location: Knoxville, TN, USA

PostPosted: Sat 29 May 2010, 12:34    Post_subject:  

I'm not as familiar with 4.3.1 as I am with the 4.1.x series since I never used it regularly. Most of the process is probably the same. I think the bootscripts might have changed a little, and some of the package versions are different. Some of the extra scripts I made may or may not work. Most of those are just for simplicity though - e.g. being able to mount/unmount drives and reboot without having to use sudo.

I know nothing at all about what changes gray has made. Maybe there are some hardcoded paths in the XFCE configuration that would need to be adjusted when it is copied into your new home directory (usually config files can't have variable paths and must be hardcoded).

Basically, this can be done on any Puppy, it's just a matter of how much work is involved. The general parts of these directions should apply to just about anything. The more specific stuff - references to individual files, for example - are less broad. You would need to investigate to see if there are any new files that need to be edited that I didn't list. The grep command is great for that kind of thing.

_________________
Between depriving a man of one hour from his life and depriving him of his life there exists only a difference of degree. --Muad'Dib

Back to top
View user's profile Send_private_message Visit_website 
Display_posts:   Sort by:   
Page 1 of 2 Posts_count   Goto page: 1, 2 Next
Post_new_topic   Reply_to_topic View_previous_topic :: View_next_topic
 Forum index » House Training » HOWTO ( Solutions )
Jump to:  

Rules_post_cannot
Rules_reply_cannot
Rules_edit_cannot
Rules_delete_cannot
Rules_vote_cannot
You cannot attach files in this forum
You can download files in this forum


Powered by phpBB © 2001, 2005 phpBB Group
[ Time: 0.2832s ][ Queries: 13 (0.0227s) ][ GZIP on ]