A sample inetd.conf file is shown here. It contains entries for the most commonly used Internet services:

ftp     stream  tcp     nowait  root    /usr/sbin/in.ftpd
  in.ftpd -l
telnet  stream  tcp     nowait  root    /usr/sbin/in.telnetd
name    dgram   udp     wait    root    /usr/sbin/in.tnamed
shell   stream  tcp     nowait  root    /usr/sbin/in.rshd
login   stream  tcp     nowait  root    /usr/sbin/in.rlogind
exec    stream  tcp     nowait  root    /usr/sbin/in.rexecd
comsat  dgram   udp     wait    root    /usr/sbin/in.comsat
talk    dgram   udp     wait    root    /usr/sbin/in.talkd
uucp    stream  tcp     nowait  root    /usr/sbin/in.uucpd
tftp   dgram   udp     wait    root    /usr/sbin/in.tftpd
  in.tftpd -s /tftpboot
finger  stream  tcp     nowait  nobody  /usr/sbin/in.fingerd
systat stream  tcp     nowait  root    /usr/bin/ps
  ps -ef
netstat        stream  tcp     nowait  root    /usr/bin/netstat
  netstat -f inet
time    stream  tcp     nowait  root    internal
time    dgram   udp     wait    root    internal
echo    stream  tcp     nowait  root    internal
echo    dgram   udp     wait    root    internal
discard stream  tcp     nowait  root    internal
discard dgram   udp     wait    root    internal
daytime stream  tcp     nowait  root    internal
daytime dgram   udp     wait    root    internal
chargen stream  tcp     nowait  root    internal
chargen dgram   udp     wait    root    internal
100232/10       tli     rpc/udp wait root /usr/sbin/sadmind     sadmind
rquotad/1       tli     rpc/datagram_v  wait root
  /usr/lib/nfs/rquotad  rquotad
rusersd/2-3     tli     rpc/datagram_v,circuit_v        wait root
  /usr/lib/netsvc/rusers/rpc.rusersd    rpc.rusersd
sprayd/1        tli     rpc/datagram_v  wait root
  /usr/lib/netsvc/spray/rpc.sprayd      rpc.sprayd
walld/1         tli     rpc/datagram_v  wait root
  /usr/lib/netsvc/rwall/rpc.rwalld      rpc.rwalld
rstatd/2-4      tli   rpc/datagram_v wait root
  /usr/lib/netsvc/rstat/rpc.rstatd rpc.rstatd
rexd/1          tli  rpc/tcp wait root /usr/sbin/rpc.rexd
100083/1        tli     rpc/tcp wait root
  /usr/dt/bin/rpc.ttdbserverd rpc.ttdbserverd
ufsd/1 tli     rpc/*   wait    root    /usr/lib/fs/ufs/ufsd
  ufsd -p
100221/1        tli     rpc/tcp wait root
  /usr/openwin/bin/kcms_server  kcms_server
fs              stream  tcp     wait nobody /usr/openwin/lib/fs.auto
100235/1 tli rpc/tcp wait root /usr/lib/fs/cachefs/cachefsd
kerbd/4         tli     rpc/ticlts      wait    root
  /usr/sbin/kerbd  kerbd
printer         stream  tcp     nowait  root
  /usr/lib/print/in.lpd   in.lpd
100234/1        tli     rpc/ticotsord   wait    root
  /usr/lib/gss/gssd gssd
dtspc stream tcp nowait root /usr/dt/bin/dtspcd
100068/2-5 dgram rpc/udp wait root /usr/dt/bin/rpc.cmsd


Many inetd services must be mapped to a specific port number. A sample /etc/services file, shown below, defines port numbers for most of the commonly used services:

tcpmux          1/tcp
echo            7/tcp
echo            7/udp
discard         9/tcp           sink null
discard         9/udp           sink null
systat          11/tcp          users
daytime         13/tcp
daytime         13/udp
netstat         15/tcp
chargen         19/tcp          ttytst source
chargen         19/udp          ttytst source
ftp-data        20/tcp
ftp             21/tcp
telnet          23/tcp
smtp            25/tcp          mail
time            37/tcp          timserver
time            37/udp          timserver
name            42/udp          nameserver
whois           43/tcp          nickname
domain          53/udp
domain          53/tcp
bootps          67/udp
bootpc          68/udp
hostnames       101/tcp         hostname
pop2            109/tcp         pop-2
pop3            110/tcp
sunrpc          111/udp         rpcbind
sunrpc          111/tcp         rpcbind
imap            143/tcp         imap2
ldap            389/tcp
ldap            389/udp
ldaps           636/tcp
ldaps           636/udp
tftp            69/udp
rje             77/tcp
finger          79/tcp
link            87/tcp          ttylink
supdup          95/tcp
iso-tsap        102/tcp
x400            103/tcp
x400-snd        104/tcp
csnet-ns        105/tcp
pop-2           109/tcp
uucp-path       117/tcp
nntp            119/tcp         usenet
ntp             123/tcp
ntp             123/udp
NeWS            144/tcp         news
cvc_hostd       442/tcp
exec            512/tcp
login           513/tcp
shell           514/tcp         cmd
printer         515/tcp         spooler
courier         530/tcp         rpc
uucp            540/tcp         uucpd
biff            512/udp         comsat
who             513/udp         whod
syslog          514/udp
talk            517/udp
route           520/udp         router routed
klogin          543/tcp

new-rwho        550/udp         new-who
rmonitor        560/udp         rmonitord
monitor         561/udp
pcserver        600/tcp
kerberos-adm    749/tcp
kerberos-adm    749/udp
kerberos        750/udp         kdc

kerberos        750/tcp         kdc
krb5_prop       754/tcp
ufsd            1008/tcp        ufsd
ufsd            1008/udp        ufsd
cvc             1495/tcp

www-ldap-gw     1760/tcp
www-ldap-gw     1760/udp
listen          2766/tcp
nfsd            2049/udp        nfs
nfsd            2049/tcp        nfs
eklogin         2105/tcp
lockd           4045/udp
lockd           4045/tcp
dtspc           6112/tcp
fs              7100/tcp

An Example FTP Transaction

After examining the possible client FTP commands and server response codes, let's see how this transactional system actually works in practice on Solaris. The first step is to make a connection to a remote host from the local system by using the standard client:

client% ftp server
Connected to server.
220 server FTP server (SunOS 5.9) ready.
Name (server:pwatters): pwatters
331 Password required for pwatters.
230 User pwatters logged in.

In this simple transaction, a user logs in and enters their password, and a session is established. This involves the client program sending a session request, receiving a 220 response, sending a USER command ('USER pwatters'), receiving back a 331 response requesting a password, and sending the password ('PASS password'). If the username and password combination is correct, the session is established and a 230 response is generated by the server. Let's look at what happens when the incorrect password is typed:

client% ftp server
Connected to server.
220 server FTP server (SunOS 5.9) ready.
Name (server:pwatters): pwatters
331 Password required for pwatters.
530 Login incorrect.
Login failed.

In this transaction, the user logs in as before, entering their password and establishing a session. This client program then sends a session request, receiving a 220 response, then sends a USER command ('USER pwatters') and receives back a 331 response requesting a password. The client then sends the password ('PASS password'), which in this example is incorrect: a 530 response is then sent back from the server to the client, and the user is left in their local client without establishing a session. However, the connect is still open, so mistyping your password can be remedied by using the following combination:

ftp> user pwatters
331 Password required for pwatters.
230 User pwatters logged in.

Thus, the session is established, and we can proceed with retrieving or uploading files. Let's look at an example:

ftp> dir
200 PORT command successful.
150 ASCII data connection for /bin/ls (,34754) (0 bytes).
total 72573
drwxr-xr-x  13 pwatters staff 2048 Mar 27 08:43 .
dr-xr-xr-x   2 root     root  2 Mar 21 18:55 ..
-rw-r--r--   1 pwatters staff 0 Jan 27 15:42 .addressbook
-rw-r--r--   1 pwatters staff 2285 Jan 27 15:42 .addressbook.lu
-rw-r--r--   1 pwatters staff 5989 Mar 27 08:42 .bash_history
lrwxrwxrwx   1 pwatters staff 8 Mar 27 08:43 .bash_profile ->> .profile
drwxr-xr-x  16 pwatters staff 512 Mar 21 10:10 .dt
-rwxr-xr-x   1 pwatters staff 5113 Jan 27 15:59 .dtprofile
-rw-------   1 pwatters staff 10 Feb 23 13:18 .hist10161
-rw-------   1 pwatters staff 28 Feb 23 16:17 .hist11931
-rw-------   1 pwatters staff 20 Mar  7 15:30 .hist12717
-rw-------   1 pwatters staff 30 Feb 21 08:11 .hist1298
-rw-------   1 pwatters staff 24 Mar  7 16:05 .hist13069
-rw-------   1 pwatters staff 18 Feb 21 15:16 .hist1370
-rw-------   1 pwatters staff 8 Feb 21 15:21 .hist1395
-rw-------   1 pwatters staff 8 Feb 22 08:43 .hist15962
-rw-------   1 pwatters staff 100 Feb 28 11:15 .hist17367
-rw-------   1 pwatters staff 24 Feb 28 11:16 .hist17371
-rw-------   1 pwatters staff 16 Feb 22 11:14 .hist19318
-rw-------   1 paul staff 68 Mar  7 14:38 .hist1954
226 ASCII Transfer complete.
6162 bytes received in 0.092 seconds (65.34 Kbytes/s)

This is the contents of the current directory. Let's say we wanted to examine the contents of the subdirectory packages:

cd packages
250 CWD command successful.
ftp> dir
200 PORT command successful.
150 ASCII data connection for /bin/ls (,34755) (0 bytes).
total 224056
drwxr-xr-x   3 pwatters staff 1024 Mar 27 08:37 .
drwxr-xr-x  13 pwatters staff 2048 Mar 27 08:43 ..
-rw-r--r--   1 pwatters staff 2457088 Mar 17 14:37 apache-1.3.6-sol7
-rw-r--r--   1 pwatters staff 3912704 Mar 17 14:38 bash-2.03-sol7
-rw-r--r--   1 pwatters staff 12154880 Mar 27 08:18 communicator-v472
drwxr-xr-x   2 pwatters staff 512 Feb  1 07:11 communicator-v472.
-rw-r--r--   1 pwatters staff 597504 Mar 17 16:18 flex-2.5.4a-sol7-
-rw-r--r--   1 pwatters staff 59280384 Mar 17 14:42 gcc-2.95.2-sol7-
226 ASCII Transfer complete.
1389 bytes received in 0.051 seconds (26.51 Kbytes/s)

Now, let's look at the situation in which we want to retrieve a binary and an ASCII file. An example would be a Java source file (with a .java extension), which must be transferred in ASCII mode, and a Java class file (with a .class extension), which must be transferred in binary mode:

ftp> ascii
200 Type set to A.
ftp> get test.java
200 PORT command successful.
150 ASCII data connection for test.java (,34759) (117 bytes).
226 ASCII Transfer complete.
local: test.java remote: test.java
127 bytes received in 0.02 seconds (6.25 Kbytes/s)
ftp> bin
200 Type set to I.
ftp> get test.class
200 PORT command successful.
150 Binary data connection for test.class (,34760) (431 bytes).
226 Binary Transfer complete.
local: test.class remote: test.class
431 bytes received in 0.0031 seconds (137.10 Kbytes/s)

Although there are many more commands available in FTP, as previously discussed, these are the most commonly used commands and the responses associated with each kind of transfer.

Troubleshooting FTP

The most common mistake in configuring FTP is not to have a valid shells database (/etc/shells) on your system. Although you can insert any shell you like into the /etc/passwd file, if the shell is not registered in the database, users will not be able to log in. This is a security measure and prevents arbitrary shells with hidden features being used on the system.

One of the nice features of FTP is that you can test it by telnetting to the FTP port. This will allow you to issue FTP commands interactively and examine the results. It is possible to determine, using this method, whether there is a problem with the remote server or a problem with your local client. For example, if you receive a 421 response, you know that the remote FTP server is not running, in which case you can advise the administrator of the remote machine to check the status of inetd.

If your client attempts to connect to a host for a long time without receiving an acknowledgement, it's often worthwhile to check that the host is actually known through DNS. You can use the nslookup command to achieve this: if a host is not registered using DNS, you won't be able to make a connection.

If the host has a resolvable hostname, then you can use any one the network troubleshooting tools like ping or traceroute to determine whether a path exists between your local client and the remote server. If no valid path exists, you can contact the administrator of the intermediate site where the connection fails.

Checking If a Host Is Up

The easiest way to check if a remote host is accessible is to use the ping command. The following example checks whether the host emu is accessible from the host dingo:

dingo% ping emu

If emu is accessible, the following output will be generated:

emu is alive

However, if emu is not accessible, an error message similar to the following will be seen:

Request timed out

If you need to determine at what point in the network the connection is failing, the traceroute command can be used to display the path taken by packets between the two hosts as they travel across the network. For example, to observe the route of the path taken by packets from AT&T to Sun's web server, we would use the following command:

client% traceroute www.sun.com
Tracing route to wwwwseast.usec.sun.com []
over a maximum of 30 hops:
 1   184 ms   142 ms   138 ms
  2   147 ms   144 ms   138 ms
  3   150 ms   142 ms   144 ms
  4   150 ms   144 ms   141 ms  atm11-0-0-11.ia4.optus.net.au []
  5   148 ms   143 ms   139 ms
  6   490 ms   489 ms   474 ms  hssi9-0-0.sf1.optus.net.au []
  7   526 ms   480 ms   485 ms  g-sfd-br-02-f12-0.gn.cwix.net []
  8   494 ms   482 ms   485 ms  core7-hssi6-0-0.SanFrancisco.cw.net []
  9   483 ms   489 ms   484 ms  corerouter2.SanFrancisco.cw.net []
 10   557 ms   552 ms   561 ms  xcore3.Boston.cw.net []
 11   566 ms   572 ms   554 ms  sun-micro-system.Boston.cw.net []
 12   577 ms   574 ms   558 ms  wwwwseast.usec.sun.com []
Trace complete.

If the connection was broken at any point, then '*' or '!' would be displayed in place of the average connection times displayed.

Enabling FTP Access

Now that we have examined the most common uses for FTP, we will now investigate how to configure the FTP daemon. The FTP server in Solaris is installed by default during configuration and package copying, during the initial installation or upgrade process. By default, the FTP server and protocol will also be active after installation. You can check the status of the FTP server on the local system by checking whether the FTP service is enabled in the services database, and in the configuration file for the inetd superdaemon:

server# grep ftp /etc/services
ftp-data        20/tcp
ftp             21/tcp
tftp            69/udp

server# grep ftp /etc/inetd.conf
ftp     stream  tcp     nowait  root    /usr/sbin/in.ftpd       in.ftpd
# Tftp service is provided primarily for booting.  Most sites run this
#tftp   dgram   udp     wait    root    /usr/sbin/in.tftpd      in.tftpd
 -s /tftpboot

We can see that FTP is both defined as a service (ftp 21/tcp) and as a daemon that runs from within the Internet superdaemon (/usr/sbin/in.ftpd). As long as the Internet superdaemon is started up during one of the single or multiple user init states, the FTP service will start. If you ever want to disable the FTP service, you need to comment out the appropriate line in both /etc/services and /etc/inetd.conf. You can do this by entering a hash character (#) in front of the appropriate line:

#ftp             21/tcp
#ftp     stream  tcp     nowait  root    /usr/sbin/in.ftpd       in.ftpd

You can also check the process list by using the command ps -eaf | grep inetd to verify that the Internet superdaemon is running at any point in time.

Part I: Solaris 9 Operating Environment, Exam I