home | O'Reilly's CD bookshelfs | FreeBSD | Linux | Cisco | Cisco Exam  


UNIX Power Tools

UNIX Power ToolsSearch this book
Previous: 2.15 Unclutter Logins: Show Login Messages Just Once Chapter 2
Logging In
Next: 3. Logging Out
 

2.16 Approved Shells: Using Unapproved Login Shell

Since 4.2BSD, Berkeley UNIX systems have restricted chsh (or a command like it) to change your login shell only to a shell that's listed in the file /etc/shells . That's partly a safety feature, like requiring you to type your old password before you can change to a new one: it keeps other people from giving you a strange login shell as a joke. It's also for security - a way for the system administrator to give a list of shells that are robust enough to run peoples' accounts.

The usual "approved" shells are the Bourne and C shells. If you want to use another shell as your login shell and your system has /etc/shells , ask the system administrator to add your shell. The shell will need to be stored in a secure system directory to make it harder for system crackers to corrupt the shell.

If the system administrator won't approve your login shell, here's a work-around. It lets you log in with an approved shell, then automatically replace the shell with whatever you want. (For background, see article 51.9 .)

  1. If your login shell isn't C shell, use chsh or a command like it to change it to the C shell.

  2. If your new shell will be bash , you can skip this step. Otherwise:

    In your home directory, make a hard or symbolic link ( 18.4 ) directory, to your shell. Use a name starting with a minus sign ( - ); this makes the shell act like a login shell ( 51.9 ) . For example, to make a symbolic link in your home directory named -ksh to the shell /usr/local/bin/ksh , type this command:

    
    
    ./
     
    
    % 
    
    ln -s /usr/local/bin/ksh ./-ksh
    
    

  3. Add lines to the top of the .cshrc ( 2.2 ) file that replace the csh process with your login shell. (The exec ( 45.7 ) command replaces a process.)

    • If you use a Bourne-type shell that reads the .profile file at login time, use lines like these:

      
      
      
      TERM
       
      
      su
       
      
      if
       
      $?
       
      
      
      
      
      
      
      # OVERRIDE DEFAULT LOGIN C SHELL TO USE ksh.
      setenv SHELL /usr/local/bin/ksh
      # IF $TERM SET (BY login OR rlogin), START LOGIN SHELL.
      # UNFORTUNATELY, THIS MAKES su USE A LOGIN SHELL TOO.
      if ($?TERM) then
         cd
         exec -ksh   # USE "LOGIN SHELL" SYMLINK IN $HOME
      else
         exec $SHELL
      endif
      echo "******** WARNING: exec ksh FAILED ********"

      If your new login shell will be bash , you can replace the line exec -ksh above with:

      exec $SHELL -login

      because bash has a -login option that tells it to act like a login shell. Simple, eh?

    • If your new login shell is a csh -type shell that also reads .cshrc , you need to add a test to .cshrc that prevents an infinite loop. This test uses the SH_EXECD environment variable ( 6.1 ) as a flag:

      # OVERRIDE DEFAULT LOGIN C SHELL TO USE tcsh.
      if (! $?SH_EXECD) then
         setenv SH_EXECD yes
         setenv SHELL /usr/local/bin/tcsh
         # IF $TERM SET (BY login OR rlogin), START LOGIN SHELL.
         # USE switch, NOT if, DUE TO csh BUG WITH IMBEDDED else.
         # UNFORTUNATELY, THIS MAKES su USE A LOGIN SHELL TOO.
         switch ($?TERM)
         case 1:
            cd 
            exec -tcsh    # USE "LOGIN SHELL" SYMLINK IN $HOME
            breaksw
         default:
            exec $SHELL   # USE NON-LOGIN SHELL
            breaksw
         endsw
         echo "******** WARNING: exec tcsh FAILED ********"
      endif

    • The C shell may not find your new shell ( -ksh or -tcsh ) unless you have the current directory ( . ) in your search path ( 8.7 ) (put it at the end of your path!). You may also be able to use an absolute pathname ( 14.2 ) to the new shell, but that could hide the leading minus sign ( - ) and the shell might not act like a login shell.

    • Is there a chance that your new shell might be missing some day? For instance, is it on a network filesystem that might be unavailable? Then it's a good idea to wrap the new code above with a test:

      
      
      -e
       
      
      
      
      
      if (-e 
      
      my-new-shell
      
      ) then
          
      ...code to start new shell...
      
      else
          echo "*** WARNING: new shell failed.  Using csh. ***"
      endif

  4. Test your new setup:

    • Try commands that start subshells ( 38.4 ) , like su , rsh , and so on ( 2.7 ) , to be sure that they start your new shell.

    • Put the csh command set echo ( 8.17 ) at the top of your .cshrc file to be sure your commands there are working.

    • Type a command that will work only in your new shell (not in a C shell).

    • Use the ps ( 38.5 ) command ps   $$ (on System V, ps   -f   -p   $$ ) to look at your new shell process ( $$ is your shell's process ID number ( 38.3 ) ).

    • Before you log out of this shell, try logging in from somewhere else ( 2.4 ) to be sure your new shell startup files work.

  5. You're set to go.

If your login shell isn't listed in /etc/shells , the ftp ( 52.7 ) program (actually, the ftpd daemon ( 1.14 ) ) may refuse to transfer files to your account. That's partly to stop ftp access to your system through special accounts that don't have passwords, like sync , who , finger , and so on. If you use the workaround steps above, though, that shouldn't be a problem; you'll have an approved shell listed in /etc/passwd and ftp usually doesn't run your login shell, anyway.

- JP


Previous: 2.15 Unclutter Logins: Show Login Messages Just Once UNIX Power Tools Next: 3. Logging Out
2.15 Unclutter Logins: Show Login Messages Just Once Book Index 3. Logging Out

The UNIX CD Bookshelf Navigation The UNIX CD BookshelfUNIX Power ToolsUNIX in a NutshellLearning the vi Editorsed & awkLearning the Korn ShellLearning the UNIX Operating System