home *** CD-ROM | disk | FTP | other *** search
- From: purdon@athena.mit.edu (James R. Purdon III)
- Newsgroups: alt.sources
- Subject: slugnet - Multiple user conferencing system: Part 3 of 6
- Message-ID: <1990Dec20.164451.25293@athena.mit.edu>
- Date: 20 Dec 90 16:44:51 GMT
-
- The slugnet program is a multiple-user, interactive conferencing
- facility. It currently runs under a variety of System V-based and
- BSD-based operating systems (although certain functions may not be
- possible under some of these operating systems).
-
- Cut here-------------------------------------------------------------------
-
- #!/bin/sh
- # to extract, remove the header and type "sh filename"
- if `test ! -s ./slugnet.doc`
- then
- echo "writing ./slugnet.doc"
- cat > ./slugnet.doc << '\End\Of\Shar\'
- .TL
- @(#)slugnet.doc 1.2
-
- .AU
- James Purdon
- .LP
- .B Introduction
- .LP
- The slugnet program is a multiple-user, interactive conferencing
- facility. It currently runs under SUNOS, UNICOS, and ULTRIX, as well as
- on machines running UNIX System V 2.x and 3.x (although certain
- functions may not be possible under some of these operating systems).
-
- .B History
- .LP
- I first got the idea for slugnet in 1985, after a short viewing of RELAY, the
- BITNET conferencing facility. Although I had written a multiple-user
- conferencing facility with multiple channels, private conferences,
- conference locking, and paging under the MUSIC/SP operating system at the
- University of Georgia, something about the RELAY format inspired me to
- write a short program (in FORTG1) which had some of the look and feel of
- RELAY.
- .PP
- Of course, user-written talk programs weren't exactly encouraged at UGA,
- so I played with it a bit, showed it to a few folks, and then abandoned
- it. That code may still be lurking about on one of my PC floppies, but
- it is for the most part lost.
- .PP
- In 1986 I gained access to another machine, a Control Data Corporation
- Cyber 180/865 running NOS 2.x (my memory is a bit hazy here). In order
- to understand it better, I decided to write a conferencing system in FTN5
- similar to the one I had done before on MUSIC. Again, I showed it to a
- few folks, but there was little interest. There were already some
- system programs that were functionally equivalent, which ran with great
- efficiency on the system's NPUs. After setting up the program in a
- script that would automatically build it, I again abandoned it (however,
- the code to this version is a part of this package and is in the file
- slugnet.n).
- .PP
- Shortly after I had completed the FTN5 version, I obtained a copy of
- Microsoft Quick C for my PC XT in order to learn c. At the time I was
- running a multiple-user, multitasking OS on my PC called Wendin Dos, and
- I decided for a lark to port slugnet to c.
- .PP
- Late in 1987 I was able to upgrade my PC XT to a PC AT and for the
- first time I was able to run UNIX. Again I ported slugnet as a learning
- experience.
- .PP
- Since then, I have ported slugnet just about every time I have learned a
- new operating system or encountered a different hardware platform. Its
- been quite helpful in illustrating where a particular UNIX-variant is
- different from what I'm accustomed too. The latest modifications I've
- made allow it to run as a server under TCP/IP, so that users do not
- require a login in order to use it.
- .PP
- Well its a new decade and I have grand new ideas for another program.
- It seems a shame to waste the effort I put into slugnet, and I really
- like the name, so I thought I'd post it to the net for posterity.
-
- .B "How slugnet Works"
- .LP
- Slugnet uses files, lots of files. One for each active user, a central
- directory,
- and files for things like file-locking, news and command definitions.
- Each time a
- user tries to read incoming messages, there is a disk access. Every
- time a user writes a message, there is a disk access for each recipient.
- If the user selects to read messages continuously, there is a disk
- access each interval specified by the "set delay" command. If you are
- on a system with fast i/o, you won't be bothered, but otherwise you may
- suffer a performance penalty.
- .PP
- There is a local program "slugnet" and a network server "slugnetd".
- Neither requires the other to be present, and both use the same files
- for communication. If you don't want to service the net, you don't have
- to.
- .PP
- By default, slugnet is setuid to whatever account owns slugnet. I
- recommend creating its own account rather than using root. It is setuid
- to protect the privacy of user messages and to keep malicious users from
- wreaking havoc. You could try to use ignorance to protect the files, if
- you don't want to run it setuid.
- .PP
- Running slugnet setuid brings up some problems. There are a series of
- commands the user can execute to do things like save configurations,
- message buffers, and incoming messages, run slugnet scripts, and read in
- files to be transmitted as messages (of course none of these commands
- make sense for users of the network server and should not be
- permitted).
- In UNIX System V a user process may switch back and forth between the
- real and effective uid but under some BSD-based systems this is not
- possible. Under these systems it is necessary to limit what the user
- may do (in fact, it is the default state for all systems).
- .PP
- Slugnet controls the users access to various commands through a
- privilege mechanism. Default privileges are assigned in the routine
- getcfg and defined in slugnet.h. These may be over-ridden by a pri or a
- net entry in the slugnet configuration file for slugnet and slugnetd
- respectively. The privileges are described by a single letter and are as
- follows:
- .PP
- a : administrative commands.
- .PP
- b : broadcast allowed.
- .PP
- d : redirection allowed.
- .PP
- f : file access allowed.
- .PP
- j : join command allowed.
- .PP
- n : set name command allowed.
- .PP
- p : private messages allowed.
- .PP
- r : ring command allowed.
- .PP
- s : shell access allowed.
- .LP
- Of these, d, f, and s are affected by the setuid problem.
- .PP
- The number of users slugnet can support is limited only by the number of
- processes on your system. Each user executes his/her own copy of the
- program.
-
- .B "Configuring slugnet"
- .LP
- Slugnet reads a configuration file in the slugnet directory
- named "slugsys.dat". This file contains lines of the following format:
-
- .ce 1
- keyword=value
- .LP
- The valid keywords and options follow:
- .LP
- .B acc
- Access mode (default "immediate"). In slugnet's sorted past,
- it once had its own login
- routine. Access was granted to new users based on the value of this
- keyword. The acceptable values were "immediate",
- "delayed", and "denied."
- .LP
- .B act
- Accounting file name (default "slugact.dat"). The file in the slugnet
- directory that contains
- accounting records.
- .LP
- .B bgn
- Prelogin file name (default "slugbgn.dat"). This once served as slugnet's
- prelogin file. Since
- the login routines were removed, it's not much different than news.
- .LP
- .B bil
- Billing mode (default "off"). Obsolete.
- Acceptable values are "on" or "off".
- .LP
- .B blf
- Billing file name (default "slugbil.dat"). Obsolete. Where user billing
- information was kept.
- .LP
- .B def
- Definition file name (default "slugdef.dat"), user or system.
- If you run slugnet on System V
- with user file privileges, this is the default name of the user
- definition file (where users define their own commands). For slugnetd,
- and slugnet on BSD-based systems, it is a file for system-wide
- definitions.
- .LP
- .B dir
- Directory file name (default "slugdir.dat"). Obsolete. Where user
- registration information was kept.
- .LP
- .B hlp
- Help file name (default "slughlp.dat"). The help file. New topics may
- be added, but not after the line that begins with the string "*EOF:".
- Each topic should be indicated by a line containing an asterisk, the
- topic name in upper case, and a trailing colon.
- .LP
- .B jsn
- Jsn file name (default "slugjsn.dat"). The jsn is part of the unique
- identifier assigned to every slugnet user (the host name is the
- remaining part).
- .LP
- .B log
- Use login mode (default "off" ). Obsolete.
- Acceptable values are "on" or "off".
- .LP
- .B mod
- Modem initialization string (default "ATZ S0=1 X1 E0 V0 S2=128"). Very
- obsolete.
- .LP
- .B new
- News file name (default "slugnew.dat"). A file that is displayed after
- the user connects (in early versions, after the user logged in).
- .LP
- .B net
- Permission set for slugnetd (default PRIVS). See above for details.
- .LP
- .B por
- Communications port. Obsolete.
- .LP
- .B pri
- Permission set for slugnet (default PRIVS). See above for details.
- .LP
- .B pro
- User/system prologue file (default "slugpro.dat"). Commands to be
- executed once user has connected to slugnet.
- .LP
- .B usr
- User file name (default "slugusr.dat"). This is the table of
- currently active users.
- .LP
- .B val
- Validation file (default "slugval.dat"). Obsolete. Where login
- information was kept.
- .PP
- You might wish to create a definition file to make things easier for
- users who might be used to other conferencing systems. Here is a copy
- of mine:
-
- .br
- *
- .br
- * for IRC users
- .br
- *
- .br
- /bye=exit;
- .br
- /expert=set novice off;
- .br
- /irc=set continuous on;
- .br
- /join=join;
- .br
- /names=show confer;
- .br
- /nick=set name;
- .br
- /quit=quit;
- .br
- /who *=show members;
- .br
- /who=show confer;
- .br
- *
- .br
- * abbreviations
- .br
- *
- .br
- se conf=set configuration;
- .br
- se cont=set continuous;
- .br
- se def=set definition;
- .br
- se del=set delay;
- .br
- se echop=set echoplex;
- .br
- se e=set echo;
- .br
- se l=set login;
- .br
- se na=set name;
- .br
- se no=set novice;
- .br
- se prol=set prolog;
- .br
- se prom=set prompt;
- .br
- se r=set ring;
- .br
- se t=set timer;
- .br
- se w=set wait;
- .br
- sh b=show buffer;
- .br
- sh confe=show confer;
- .br
- sh confi=show configuration;
- .br
- sh h=show hosts;
- .br
- sh l=show logins;
- .br
- sh m=show members;
- .br
- sh m=show members;
-
- .B "Administrative commands"
- .LP
- Currently, slugnet has only one administrative command, "show all",
- which shows all the users on all the conferences whether they are
- invisible or not. The earliest versions had another command, which began
- with a "$" and contained a target jsn and command. When executed, it
- forced the target jsn to execute the command (this is, in fact how the
- ring command works, by forcing the target jsn to execute the bell
- command). Since the owner of slugnet (but not slugnetd) has access to
- the shell, and owns all slugnet and slugnetd process, I removed the
- second command as unnecessary. If you need to kill a user, use "show
- all" to get his/her pid, and use the shell escape and the Unix kill
- command to send it a signal - I recommend "kill -1".
- .PP
- Slugnet needs very little in the way of maintenance. The accounting
- file should be flushed at regular intervals and the status of the
- network server ought to be checked once in a while. I also try to
- collect any error messages slugnetd may issue.
- .PP
- I've changed my rc.local to start up slugnetd on reboot by adding the
- following line:
-
- echo 'rm slugusr.dat; /usr/local/bin/slugnetd &' | su - slugnet >/dev/null
-
- .B "Access Control"
- .LP
- Neither slugnet or slugnetd provide access control. If you desire to
- add your own access control, I suggest that it be added into slugnet.c.
- The easiest thing to do might be to use some of the obsolete keywords in
- getcfg.c (like val) to point to a validation file and use a grep to see
- if a particular host or user was validated. When creating a validation
- mechanism, it is important to note that for remote users, only the
- host name can be validated (you might want to see how the "set login"
- command attempts to validate remote users).
-
- .B "Suggestions for modifications"
-
- .LP
- 1. A slugnet-specific client would be very nice, as it would solve all
- setuid-related problems.
- .LP
- 2. I worked a bit on a distributed-server model (not quite entirely
- unlike IRC) but abandoned it when it became clear to me that the server
- would have to be changed in a way that I felt was unfriendly to remote
- users. My hacks are set off by the def SERVER. If you compile slugnetd
- with SERVER, you'd better have some sort of access control.
- .LP
- 3. I suppose that conference and server operators might be nice, but I
- think they are more trouble than they are worth. If you need to control
- your users that much, you probably shouldn't be running slugnet.
-
- .B "Accounting file format"
- .LP
- All fields are separated by colons.
-
- .br
- Field 1: login@host
- .br
- Field 2: jsn
- .br
- Field 3: bytes input
- .br
- Field 4: bytes output
- .br
- Field 5: login time in seconds from 1970
- .br
- Field 6: logout time in seconds from 1970
- .br
- Field 7: connect time in seconds
- .br
- Field 8: day name, month, day, military time, and year.
-
- \End\Of\Shar\
- else
- echo "will not over write ./slugnet.doc"
- fi
- chmod 400 ./slugnet.doc
- if [ `wc -c ./slugnet.doc | awk '{printf $1}'` -ne 11723 ]
- then
- echo `wc -c ./slugnet.doc | awk '{print "Got " $1 ", Expected " 11723}'`
- fi
- if `test ! -s ./slugnet.h`
- then
- echo "writing ./slugnet.h"
- cat > ./slugnet.h << '\End\Of\Shar\'
- /* @(#)slugnet.h 1.13 */
- #include "copyright.h"
-
- #include <stdio.h>
- #include <fcntl.h>
-
- #ifdef SUNOS
- #define O_FSYNC O_SYNC
- #endif
-
- #if defined( SYSV3 ) && !defined( UNICOS )
-
- #include <filehdr.h>
- #include <scnhdr.h>
-
- #endif
-
- #ifdef SYSV2
-
- #include <filehdr.h>
- #include <scnhdr.h>
- #include <ldfcn.h>
-
- #endif SYSV2
-
- #include <unistd.h>
- #ifdef INTERLAN
- #include <interlan/il_types.h>
- #else
- #include <sys/types.h>
- #endif
- #include <sys/stat.h>
- #include <signal.h>
- #ifdef INTERLAN
- #define SIGCHLD SIGCLD
- #define SIGURG SIGUSR2
- #endif INTERLAN
-
- #define ON 1
- #define OFF 0
- #define CRLF 1
- #define NOCRLF 0
-
- #define BS 8
- #define CR 13
- #define DEL 127
- #define LF 10
-
- #define CFRLEN 32
- #define FLNMLN 16
- #define JSNLEN 5
- #define LINLEN 80
-
- #define NAMLEN 32
-
- #define UNLEN 8
-
- #define HOSTLEN 64
- #define PIDLEN 32
- #define MODELN 2
-
- #define ADD 0
- #define ALLOW 1
- #define DELAY 2
- #define DENY -1
- #define RETRY -2
-
- #define ADMIN 1
- #define DEBUG 0
- #define LOGIN 1
- #define MSGLEN 2048
- #define PRMLEN 34
-
- #define DIRLEN 80
-
- #define TIMEOUT 5
-
- #define BLANKS " "
-
- char *strcat(),*strcpy(),*strncpy(),*strchr(),*strrchr();
- #ifdef BSD4
- char *sprintf();
- #endif BSD4
-
- int hungup;
- int stopscroll;
-
- struct slugdir
- {
- char name[ NAMLEN ];
- char un[ UNLEN ];
- char jsn[ JSNLEN ];
- char confer[ CFRLEN ];
- char rcvfil[ FLNMLN ];
- char host[ HOSTLEN ];
- char pid[ PIDLEN ];
- char mode[ MODELN ];
- };
-
- /* default privileges */
-
- #ifdef SYSV2
- #ifndef NETWORK
- #define PRIVS "_bfjnprs"
- #else
- #define PRIVS "_bjnpr"
- #endif
- #endif SYSV2
- #ifdef SYSV3
- #ifndef NETWORK
- #define PRIVS "_bfjnprs"
- #else
- #define PRIVS "_bjnpr"
- #endif
- #endif SYSV3
- #ifdef BSD4
- #ifndef NETWORK
- #define PRIVS "_bjnpr"
- #else
- #define PRIVS "_bjnpr"
- #endif
- #endif BSD4
- #ifdef ULTRIX
- #ifndef NETWORK
- #define PRIVS "_bjnpr"
- #else
- #define PRIVS "_bjnpr"
- #endif
- #endif ULTRIX
-
- \End\Of\Shar\
- else
- echo "will not over write ./slugnet.h"
- fi
- chmod 400 ./slugnet.h
- if [ `wc -c ./slugnet.h | awk '{printf $1}'` -ne 1864 ]
- then
- echo `wc -c ./slugnet.h | awk '{print "Got " $1 ", Expected " 1864}'`
- fi
- if `test ! -s ./slugnet.mk`
- then
- echo "writing ./slugnet.mk"
- cat > ./slugnet.mk << '\End\Of\Shar\'
- #
- # @(#)slugnet.mk 1.7: makefile for $(SLUGNET)
- #
- # Empty macros are set by calling makefile
- #
- SLUGBIN =
- SLUGDIR =
- SLUGUID =
- OS =
- SLUGNET =
- MAN =
- NETFLG =
- #
- SLGFLG = -DSLUGDIR=\"$(SLUGDIR)\"
- CFLAGS = $(OS) $(SLGFLG) $(NETFLG)
- #
- DATA = slughlp.dat
-
- DOCS = Readme slugnet.1 slugnetd.1 slugnet.doc slugnet.n
-
- HEADERS = copyright.h net.h slugnet.h
-
- MAKES = Makefile slugnet.mk
-
- OBJECTS = call_socket.o callbyaddr.o callbyhost.o chgusr.o cleanup.o\
- clnusr.o establish.o find.o get_connect.o getcfg.o getjsn.o lock.o\
- lower.o main.o rdline.o receive.o repchar.o send_file.o setjsn.o\
- sighang.o sigquit.o sigstop.o sigterm.o sigtstp.o sigurg.o slugnet.o\
- strnicmp.o task.o transmit.o unlock.o verify.o
-
- SOURCES = call_socket.c callbyaddr.c callbyhost.c chgusr.c cleanup.c\
- clnusr.c establish.c find.c get_connect.c getcfg.c getjsn.c lock.c\
- lower.c main.c rdline.c receive.c repchar.c send_file.c setjsn.c\
- sighang.c sigquit.c sigstop.c sigterm.c sigtstp.c sigurg.c slugnet.c\
- strnicmp.c task.c transmit.c unlock.c verify.c
-
- $(SLUGNET): $(OBJECTS)
- cc $(OBJECTS) $(LDFLAGS) -o $(SLUGNET)
- #
- # routines
- #
- call_socket.o: net.h call_socket.c
-
- callbyaddr.o: net.h callbyaddr.c
-
- callbyhost.o: net.h callbyhost.c
-
- cleanup.o: net.h cleanup.c
-
- chgusr.o: slugnet.h chgusr.c
-
- establish.o: net.h establish.c
-
- find.o: slugnet.h find.c
-
- get_connect.o: net.h get_connect.c
-
- getcfg.o: slugnet.h getcfg.c
-
- getjsn.o: slugnet.h getjsn.c
-
- lock.o: slugnet.h lock.c
-
- lower.o: slugnet.h lower.c
-
- main.o: net.h main.c
-
- slugnet.o: slugnet.h slugnet.c
-
- rdline.o: slugnet.h rdline.c
-
- receive.o: slugnet.h receive.c
-
- repchar.o: slugnet.h repchar.c
-
- send_file.o: slugnet.h send_file.c
-
- setjsn.o: slugnet.h setjsn.c
-
- sighang.o: slugnet.h sighang.c
-
- sigquit.o: slugnet.h sigquit.c
-
- sigstop.o: slugnet.h sigstop.c
-
- sigterm.o: slugnet.h sigterm.c
-
- sigtstp.o: slugnet.h sigtstp.c
-
- sigurg.o: slugnet.h sigurg.c
-
- strnicmp.o: slugnet.h strnicmp.c
-
- task.o: net.h task.c
-
- transmit.o: slugnet.h transmit.c
-
- unlock.o: slugnet.h unlock.c
-
- verify.o: net.h verify.c
-
- clean:
- @echo "Removing objects..."
- @rm -f $(OBJECTS)
-
- install: $(SLUGDIR) $(SLUGBIN)
- @echo "Installing $(SLUGNET)..."
- cp $(SLUGNET) $(SLUGBIN)/$(SLUGNET)
- chown $(SLUGUID) $(SLUGBIN)/$(SLUGNET)
- @size $(SLUGBIN)/$(SLUGNET)
- chmod u+s $(SLUGBIN)/$(SLUGNET)
- chmod oug+x $(SLUGBIN)/$(SLUGNET)
- cp slughlp.dat $(SLUGDIR)/slughlp.dat
- chmod og-w $(SLUGDIR)/slughlp.dat
- chmod u+w $(SLUGDIR)/slughlp.dat
- chmod uog+r $(SLUGDIR)/slughlp.dat
- chown $(SLUGUID) $(SLUGDIR)/*
- @echo "Installing man page for $(SLUGNET)..."
- cp $(SLUGNET).1 $(MAN)/$(SLUGNET).1
- chmod og-w $(MAN)/$(SLUGNET).1
- chmod u+w $(MAN)/$(SLUGNET).1
- chmod uog+r $(MAN)/$(SLUGNET).1
- #
- # if slugnet is NOT setuid $(SLUGUID), following statement should be
- # uncommented.
- #
- # chmod oug+rw $(SLUGDIR)
- $(SLUGBIN):
- mkdir $(SLUGBIN)
- $(SLUGDIR):
- mkdir $(SLUGDIR)
- #
- # tar
- #
- slugtar: $(DATA) $(DOCS) $(HEADERS) $(MAKES) $(SOURCES)
- tar -cvf slugtar $(DATA) $(DOCS) $(HEADERS) $(MAKES) $(SOURCES)
- \End\Of\Shar\
- else
- echo "will not over write ./slugnet.mk"
- fi
- chmod 400 ./slugnet.mk
- if [ `wc -c ./slugnet.mk | awk '{printf $1}'` -ne 3035 ]
- then
- echo `wc -c ./slugnet.mk | awk '{print "Got " $1 ", Expected " 3035}'`
- fi
- echo "Finished archive 3 of 6"
- exit
-