Re: Logging users out

2000-11-04 Thread andrew



On Tue, 31 Oct 2000, Terry Lambert wrote:

 not noticing that read was returning 0 (which is returned on EOF,
 but is also returned on perfectly goo non-blocking fds, and in the

If you read from a non blocking fd (and there is nothing to read) don't
you get -1 and errno = EAGAIN?

 case that vmin is set to zero to effect a timed poll via vtime).

That seems to be a problem.

Andrew



To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-hackers" in the body of the message



Re: Logging users out

2000-11-04 Thread andrew



On Tue, 31 Oct 2000, Terry Lambert wrote:

 (struct tty *)-t_pgrp-pg_id
 
 Which is the process ID of the group leader of the foregroun
 group.

Isn't this what tcgetpgrp returns? Problem with this is that it probably
isn't the PID of the session leader. Wouldn't I need (struct tty
*)-t_session-s_leader-p_pid?

Of course I could be wrong :-)

 Or you could just make revoke do its thing in the right order
 instead of the wrong order,

I've been looking at that...but it takes a lot of looking it seems :-). I
shall persevere.

Thanks,

Andrew




To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-hackers" in the body of the message



Re: Logging users out

2000-10-31 Thread Terry Lambert

  Uh, well, "foolproof" != "calling ps and awk and grep and looking for
  processes".  For ANY definition of foolproof.
  
  And it is certainly foolproof from the point of view that there's no way
  in hell for the session not to be terminated, unlike some ps garbage I've
  seen.
 
 Unfortunatly, sometimes when processes suddenly lose stdin/stdout,
 they jump into infinate loops and start eating cpu cycles like
 crazy.  I'd hate to see what happens when you kill off a
 significant number of people running these poorly behaved programs.
 FVWM95 Taskbars used to be notorious for this, I remember seeing
 upwards of a dozen of them vying for CPU time on some lab
 machines.

This is because the FreeBSD tty revocation code is broken, though
in technical compliance with POSIX.

The way it's supposed to happen is that "hupcl" (hangup on close)
is supposed to be set on the tty, and the signal is supposed to
be sent to the process group leader, so it can be trampolined.
Being a group signal, not a process signal, it will be delivered
to all children of the leader, as well -- just as group signal
delivery has been supposed to work for forever.  Only by the
time it gets there, there aren't any children technically in
the group any more.

What happens in the revoke code is that effectively, everyone is
made into a process group leader, so the SIGHUP to the process
group leader is not properly propagated to the other processes
in the group.

The correct order of operation is to revoke, promote, then signal,
which would result in the SIGHUP being delivered to all processes
which have not explicitly blocked it.  FreeBSD does revoke, signal,
then promote, which means the newly promotes processes aren't in
the signalled process group by the time the SIGHUP is delivered.

Traditional BSD (and UNIX) behaviour actually iteratively did
the revocation of the controlling tty on a per process basis,
after signal delivery, but the global "revoke" changed things.

This change went in during the POSIX-me-harder tournament, early
in FreeBSD's infancy.  Before it was POSIX-ized, SIGHUP was
correctly delivered on hangup to _all_ processes for which the
tty was the controlling tty.  After it went in, we started having
runaway processes, which were then labelled as being "broken" for
not noticing that read was returning 0 (which is returned on EOF,
but is also returned on perfectly goo non-blocking fds, and in the
case that vmin is set to zero to effect a timed poll via vtime).

Yeah, I basically replay this broken record any time someone
tries to blame the application for not getting out the Ouiji
board and trying to contact the dear departed tty, since there
are actually people who really do use non-blocking fds and vmin/vtime
to do things like user space threads and background computation
while waiting for user input.


Terry Lambert
[EMAIL PROTECTED]
---
Any opinions in this posting are my own and not those of my present
or previous employers.


To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-hackers" in the body of the message



Re: Logging users out

2000-10-31 Thread Terry Lambert

  Why not just kill their controlling shell?
 
 I believe that what I'm doing...the "controlling shell" would be the
 session leader. The question is how to get its PID.

Grovel the tty structure using libkvm.

You want to look for:

(struct tty *)-t_pgrp-pg_id

Which is the process ID of the group leader of the foregroun
group.

Or you could just make revoke do its thing in the right order
instead of the wrong order, since a program with non-blocking
fds (read: any threads program) would have to be clairvoyant
(or check every time by trying to open /dev/tty, and noting when
that failed).


Terry Lambert
[EMAIL PROTECTED]
---
Any opinions in this posting are my own and not those of my present
or previous employers.


To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-hackers" in the body of the message



Re: Logging users out

2000-10-31 Thread Jamie Heckford

On Tue, 31 Oct 2000, you wrote:
 On Tue, Oct 31, 2000 at 01:40:32PM +0100, Thierry Besancon thus spoke:
  Dixit Bill Vermillion [EMAIL PROTECTED] (le Tue, 31 Oct 2000 07:22:55 -0500) :
  
  »  % ps -aux | grep username
  » 
  »  username   1637  1.3  0.7  1340  868  p1  Ds   11.36AM  0:00.09  csh
  » 
  »  then I just do a:
  » 
  »  % kill -KILL 1637
  » 
  »  not the best or cleanest way of doing it, but its just a quick
  »  method ive stuck with over the years.
  » 
  » Definately not the cleanest/best.  What's wrong with -HUP.
  » 
  » -KILL [aka -9] give no chance for proper file closure and cleanup.
  
  When you kill -HUP a csh, it just remains. Nothing happens. You have
^^^
  to kill -9 it to get rid of it. Just try.
 
 That explains that.  I've studiously avoided csh for the past 15
 years.  Shows I've not worked around a Sun environment much,
 doesn't it?  Ever thought of using a better shell :-) [Add LOTS of
 smileys here - I'm not going to get into a shell wars argument -
 what works best for you, works best for you.  I'm a ksh user].
 
 -- 
 Bill Vermillion -   bv @ wjv . com
 
 
 To Unsubscribe: send mail to [EMAIL PROTECTED]
 with "unsubscribe freebsd-isp" in the body of the message
-- 
Jamie Heckford
Chief Network Engineer
Psi-Domain - Innovative Linux Solutions. Ask Us How.

===
email: [EMAIL PROTECTED]
web: http://www.psi-domain.co.uk/

tel:   +44 (0)1737 789 246
fax:   +44 (0)1737 789 245
mobile:+44 (0)7779 646 529
===


To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-hackers" in the body of the message



Re: Logging users out

2000-10-30 Thread Ryan Thompson

[EMAIL PROTECTED] wrote to [EMAIL PROTECTED]:

 Hi,
 
 What is the best way to go about logging a user out given their tty? I had
 a couple of ideas:
 
 (a) open their tty and set the baud rate to 0

Probably wouldn't be very effective.
 

 (b) use tcgetpgrp to get the process group id of the foreground process
 group on that tty, then with that info use libkvm to find the session
 leader's pid and send it a SIGHUP

Why not just kill their controlling shell?  That's about all a logout will
do, anyway.  If they have processes detatched from the controlling
terminal, the user typing "logout" will not stop them.

Recall that "background" and "foreground" are shell concepts, not
properties of any given process.


 (c) use tcgetpgrp to get the process group id of the foreground process
 group on that tty then using killpg to kill all the members of that
 process group. I would need to do this in a loop to catch background
 process groups that come to the foreground after a process group is
 killed.
 
 Whenever sending a signal I will have to verify the process exited,
 possibly sending TERM and KILL until it does.
 
 Problems:
 
 (a) a doesn't seem to work...I'm guessing it only works on serial lines.
 
 (b) b would be quite unportable I would guess (although thats not a
 tragedy I would like to avoid it if it isn't too hard). Also if the
 session leader dies is there any guarentee everything else in the session
 goes as well? Or would I have to go through and kill every process group
 in the session?

Never any guarantee.. user programs can set up signal handlers to catch or
ignore any signal but SIGKILL.  Then again, a user typing "logout" will
not clean up absolutely everything, either.


 (c) c just seemed to be a bit of a hack (assuming you haven't just read
 b). Out of all of them it seems the best so far however.
 
 Does anyone have any suggestions or comments? Is there a "proper" way to
 do this?

a) Kill the controlling shell.  This will leave some processes behind that
   are no longer part of the user's session (like programs that have
   detatched from the terminal and become daemons), and processes that
   were never part of the user's session (like processes that they started
   on a different terminal)

b) kill -signal `ps -axo user,pid | grep user | awk '{print $2}'`
   Kills every process owned by ``user''.  Sending SIGKILL does so
   in a non-catchable way.

c) /sbin/halt is pretty much guaranteed to do the trick ;-)


 
 Thanks,
 
 Andrew
 
 
 
 
 To Unsubscribe: send mail to [EMAIL PROTECTED]
 with "unsubscribe freebsd-hackers" in the body of the message
 

-- 
  Ryan Thompson [EMAIL PROTECTED]
  Network Administrator, Accounts
  Phone: +1 (306) 664-1161

  SaskNow Technologies http://www.sasknow.com
  #106-380 3120 8th St E   Saskatoon, SK  S7H 0W2



To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-hackers" in the body of the message



Re: Logging users out

2000-10-30 Thread andrew



On Mon, 30 Oct 2000, Ryan Thompson wrote:

  (b) use tcgetpgrp to get the process group id of the foreground process
  group on that tty, then with that info use libkvm to find the session
  leader's pid and send it a SIGHUP
 
 Why not just kill their controlling shell?

I believe that what I'm doing...the "controlling shell" would be the
session leader. The question is how to get its PID.

 Recall that "background" and "foreground" are shell concepts, not
 properties of any given process.

No they are properties of process groups. Each session can have one
foreground process group and multiple background session groups. The
foreground process group is the one that receives signals and input from
the session's controlling terminal.

 a) Kill the controlling shell.  This will leave some processes behind that

The question is how to get its PID?

 b) kill -signal `ps -axo user,pid | grep user | awk '{print $2}'`

I only want to grab those on the one tty but thats an easy enough
modification.

 c) /sbin/halt is pretty much guaranteed to do the trick ;-)

but sadly rather intrusive on other ttys :-)

Thanks for your help,

Andrew



To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-hackers" in the body of the message



Re: Logging users out

2000-10-30 Thread Joe Greco

 a) Kill the controlling shell.  This will leave some processes behind that
are no longer part of the user's session (like programs that have
detatched from the terminal and become daemons), and processes that
were never part of the user's session (like processes that they started
on a different terminal)
 
 b) kill -signal `ps -axo user,pid | grep user | awk '{print $2}'`
Kills every process owned by ``user''.  Sending SIGKILL does so
in a non-catchable way.
 
 c) /sbin/halt is pretty much guaranteed to do the trick ;-)

d) revoke() their tty

I used to do variations on a) and b) above, but it's messy, time consuming,
error prone, and requires ugly changes every time someone changes ps output,
features, or whatever.

I wrote a little line program to do a revoke(), it was basically

int main(int argc, char *argv[]) { revoke(argv[1]); }

Now this doesn't kill a darn thing.  And you should be aware of it!  But it
does forcibly "close" any open fd's pointing at the tty in question, and
most programs will get the hint and go away.

For some uses, especially predictable uses, this is probably a lot simpler
and a lot more foolproof.
-- 
... Joe

---
Joe Greco - Systems Administrator [EMAIL PROTECTED]
Solaria Public Access UNIX - Milwaukee, WI 414/342-4847


To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-hackers" in the body of the message



Re: Logging users out

2000-10-30 Thread Joe Greco

  I wrote a little line program to do a revoke(), it was basically
  
  int main(int argc, char *argv[]) { revoke(argv[1]); }
  
  Now this doesn't kill a darn thing.  And you should be aware of it!  But it
  does forcibly "close" any open fd's pointing at the tty in question, and
  most programs will get the hint and go away.
 
 Not all programs, and that can lead to all sorts of problems
 with processes that never die.  There are many stories of this
 happening with vi, for example.

That's why I said, "most programs".

  For some uses, especially predictable uses, this is probably a lot simpler
  and a lot more foolproof.
 
 Simple: yes.  Foolproof: definitely no.

Uh, well, "foolproof" != "calling ps and awk and grep and looking for
processes".  For ANY definition of foolproof.

And it is certainly foolproof from the point of view that there's no way
in hell for the session not to be terminated, unlike some ps garbage I've
seen.

It's also an interesting way for a user without root permissions to "kill"
a suid process of some sort that happens to be running on a tty owned by 
the user - which can happen.  But, again, it relies on proper attention by
programs to dying upon close of std{out,in}.
-- 
... Joe

---
Joe Greco - Systems Administrator [EMAIL PROTECTED]
Solaria Public Access UNIX - Milwaukee, WI 414/342-4847


To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-hackers" in the body of the message



Re: Logging users out

2000-10-30 Thread Wes Peters

Joe Greco wrote:
 
   I wrote a little line program to do a revoke(), it was basically
  
   int main(int argc, char *argv[]) { revoke(argv[1]); }
  
   Now this doesn't kill a darn thing.  And you should be aware of it!  But it
   does forcibly "close" any open fd's pointing at the tty in question, and
   most programs will get the hint and go away.
 
  Not all programs, and that can lead to all sorts of problems
  with processes that never die.  There are many stories of this
  happening with vi, for example.
 
 That's why I said, "most programs".
 
   For some uses, especially predictable uses, this is probably a lot simpler
   and a lot more foolproof.
 
  Simple: yes.  Foolproof: definitely no.
 
 Uh, well, "foolproof" != "calling ps and awk and grep and looking for
 processes".  For ANY definition of foolproof.

No, but walking the active process table looking for session leaders is
not that difficult.  In fact, this was the first program I ever wrote on
FreeBSD, back on 1.0.  Unfortunately, it was a commercial product Axent
Technologies never released, but later folded into UNIX Resource Manager
that was bought by dozens.  ;^)

-- 
"Where am I, and what am I doing in this handbasket?"

Wes Peters Softweyr LLC
[EMAIL PROTECTED]   http://softweyr.com/


To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-hackers" in the body of the message



Logging users out

2000-10-29 Thread andrew

Hi,

What is the best way to go about logging a user out given their tty? I had
a couple of ideas:

(a) open their tty and set the baud rate to 0

(b) use tcgetpgrp to get the process group id of the foreground process
group on that tty, then with that info use libkvm to find the session
leader's pid and send it a SIGHUP

(c) use tcgetpgrp to get the process group id of the foreground process
group on that tty then using killpg to kill all the members of that
process group. I would need to do this in a loop to catch background
process groups that come to the foreground after a process group is
killed.

Whenever sending a signal I will have to verify the process exited,
possibly sending TERM and KILL until it does.

Problems:

(a) a doesn't seem to work...I'm guessing it only works on serial lines.

(b) b would be quite unportable I would guess (although thats not a
tragedy I would like to avoid it if it isn't too hard). Also if the
session leader dies is there any guarentee everything else in the session
goes as well? Or would I have to go through and kill every process group
in the session?

(c) c just seemed to be a bit of a hack (assuming you haven't just read
b). Out of all of them it seems the best so far however.

Does anyone have any suggestions or comments? Is there a "proper" way to
do this?

Thanks,

Andrew




To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-hackers" in the body of the message