3

I am working with rsh. I want to check the whole process from beginning to end. For that I used strace.

Os name is CentOS. I am working on single machine, server and client are on same machine.

My command is , rsh localhost ulimit -n

To take a trace, I used strace rsh localhost ulimit -n.

I read all the files that is open during executing above command. But I want to trace how the rsh server sets the limit of ulimit -n, because all commands in rsh run by rsh daemon.

The system call I am looking for is, setrlimit, but it didn't show this system call by using strace rsh localhost ulimit -n.

For that I have to trace rsh server , i.e, rsh daemon. But I don't know, how I perform this task.

Please tell me the command and their explanations also.

I know rsh is not used in current scenario, but my project is using that, so please don't tell , rsh is not good. I know all these stuffs.

Edit No. 1

$ sudo lsof -i :514


COMMAND  PID USER    FD   TYPE DEVICE SIZE  NODE  NAME
syslogd 2210 root    9u  IPv4   6259       UDP *:syslog
xinetd  2658 root    8u  IPv4   8745       TCP *:shell (LISTEN)

and, /etc/xinetd.d, does not contain rshd, it contains rsh, rexec, rlogin, rsync, etc.

Edit no 2 [related to comment by Chris Down]

rsh localhost strace -o log_new bash -c 'ulimit -n'

It gives different answer that it gives when I run strace rsh localhost ulimit -n

execve("/bin/bash", ["bash", "-c", "ulimit", "-n"], [/* 15 vars */]) = 0
brk(0)                                  = 0x13e86000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2af7bbab2000
uname({sys="Linux", node="jhamb.XXX.XXX", ...}) = 0
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY)      = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=57641, ...}) = 0
mmap(NULL, 57641, PROT_READ, MAP_PRIVATE, 3, 0) = 0x2af7bbab3000
close(3)                                = 0
open("/lib64/libtermcap.so.2", O_RDONLY) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0@\17\300T4\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=15584, ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2af7bbac2000
mmap(0x3454c00000, 2108688, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x3454c00000
mprotect(0x3454c03000, 2093056, PROT_NONE) = 0
mmap(0x3454e02000, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x2000) = 0x3454e02000
close(3)                                = 0
open("/lib64/libdl.so.2", O_RDONLY)     = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\20\16@T4\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=23360, ...}) = 0
mmap(0x3454400000, 2109696, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x3454400000
mprotect(0x3454402000, 2097152, PROT_NONE) = 0
mmap(0x3454602000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x2000) = 0x3454602000
close(3)                                = 0
open("/lib64/libc.so.6", O_RDONLY)      = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\300\332\1T4\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=1726320, ...}) = 0
mmap(0x3454000000, 3506520, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x3454000000
mprotect(0x345414f000, 2097152, PROT_NONE) = 0
mmap(0x345434f000, 20480, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x14f000) = 0x345434f000
mmap(0x3454354000, 16728, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x3454354000
close(3)                                = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2af7bbac3000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2af7bbac4000
arch_prctl(ARCH_SET_FS, 0x2af7bbac3dd0) = 0
mprotect(0x3454602000, 4096, PROT_READ) = 0
mprotect(0x345434f000, 16384, PROT_READ) = 0
mprotect(0x3453e1c000, 4096, PROT_READ) = 0
munmap(0x2af7bbab3000, 57641)           = 0
rt_sigprocmask(SIG_BLOCK, NULL, [], 8)  = 0
open("/dev/tty", O_RDWR|O_NONBLOCK)     = -1 ENXIO (No such device or address)
ioctl(0, SNDCTL_TMR_TIMEBASE or TCGETS, 0x7fffb504cb00) = -1 EINVAL (Invalid argument)
brk(0)                                  = 0x13e86000
brk(0x13ea7000)                         = 0x13ea7000
getuid()                                = 500
getgid()                                = 500
geteuid()                               = 500
getegid()                               = 500
rt_sigprocmask(SIG_BLOCK, NULL, [], 8)  = 0
open("/proc/meminfo", O_RDONLY)         = 3
fstat(3, {st_mode=S_IFREG|0444, st_size=0, ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2af7bbab3000
read(3, "MemTotal:      3920228 kB\nMemFre"..., 4096) = 777
close(3)                                = 0
munmap(0x2af7bbab3000, 4096)            = 0
rt_sigaction(SIGCHLD, {SIG_DFL, [], SA_RESTORER, 0x3454030330}, {SIG_DFL, [], 0}, 8) = 0
rt_sigaction(SIGCHLD, {SIG_DFL, [], SA_RESTORER, 0x3454030330}, {SIG_DFL, [], SA_RESTORER, 0x3454030330}, 8) = 0
rt_sigaction(SIGINT, {SIG_DFL, [], SA_RESTORER, 0x3454030330}, {SIG_DFL, [], 0}, 8) = 0
rt_sigaction(SIGINT, {SIG_DFL, [], SA_RESTORER, 0x3454030330}, {SIG_DFL, [], SA_RESTORER, 0x3454030330}, 8) = 0
rt_sigaction(SIGQUIT, {SIG_DFL, [], SA_RESTORER, 0x3454030330}, {SIG_DFL, [], 0}, 8) = 0
rt_sigaction(SIGQUIT, {SIG_DFL, [], SA_RESTORER, 0x3454030330}, {SIG_DFL, [], SA_RESTORER, 0x3454030330}, 8) = 0
rt_sigprocmask(SIG_BLOCK, NULL, [], 8)  = 0
rt_sigaction(SIGQUIT, {0x1, [], SA_RESTORER, 0x3454030330}, {SIG_DFL, [], SA_RESTORER, 0x3454030330}, 8) = 0
uname({sys="Linux", node="jhamb.XXX.XXX", ...}) = 0
stat("/home/service", {st_mode=S_IFDIR|0700, st_size=4096, ...}) = 0
stat(".", {st_mode=S_IFDIR|0700, st_size=4096, ...}) = 0
getpid()                                = 30873
getppid()                               = 30829
stat(".", {st_mode=S_IFDIR|0700, st_size=4096, ...}) = 0
stat("/home/service/bin/bash", 0x7fffb504cab0) = -1 ENOENT (No such file or directory)
stat("/usr/local/sbin/bash", 0x7fffb504cab0) = -1 ENOENT (No such file or directory)
stat("/usr/local/bin/bash", 0x7fffb504cab0) = -1 ENOENT (No such file or directory)
stat("/usr/sbin/bash", 0x7fffb504cab0)  = -1 ENOENT (No such file or directory)
stat("/sbin/bash", 0x7fffb504cab0)      = -1 ENOENT (No such file or directory)
stat("/usr/kerberos/bin/bash", 0x7fffb504cab0) = -1 ENOENT (No such file or directory)
stat("/usr/bin/bash", 0x7fffb504cab0)   = -1 ENOENT (No such file or directory)
stat("/bin/bash", {st_mode=S_IFREG|0755, st_size=801512, ...}) = 0
access("/bin/bash", X_OK)               = 0
access("/bin/bash", R_OK)               = 0
stat("/bin/bash", {st_mode=S_IFREG|0755, st_size=801512, ...}) = 0
access("/bin/bash", X_OK)               = 0
access("/bin/bash", R_OK)               = 0
getpgrp()                               = 30829
rt_sigaction(SIGCHLD, {0x436080, [], SA_RESTORER, 0x3454030330}, {SIG_DFL, [], SA_RESTORER, 0x3454030330}, 8) = 0
rt_sigprocmask(SIG_BLOCK, NULL, [], 8)  = 0
getpeername(0, {sa_family=AF_INET, sin_port=htons(61000), sin_addr=inet_addr("127.0.0.1")}, [5255137823777882128]) = 0
rt_sigprocmask(SIG_BLOCK, NULL, [], 8)  = 0
rt_sigprocmask(SIG_BLOCK, NULL, [], 8)  = 0
getrlimit(RLIMIT_FSIZE, {rlim_cur=RLIM_INFINITY, rlim_max=RLIM_INFINITY}) = 0
fstat(1, {st_mode=S_IFSOCK|0777, st_size=0, ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2af7bbab3000
write(1, "unlimited\n", 10)             = 10
exit_group(0)                           = ?

Edit No.3

# grep -e ulimit -e setrlimit rsh.strace.



rsh.strace.31472:14:22:42.966361 setrlimit(RLIMIT_NOFILE, {rlim_cur=1024, rlim_max=1024}) = 0
rsh.strace.31474:14:22:43.085822 execve("/bin/bash", ["bash", "-c", "ulimit -n"], [/* 4 vars */]) = 0
rsh.strace.31474:14:22:43.546754 setrlimit(RLIMIT_CORE, {rlim_cur=RLIM_INFINITY, rlim_max=RLIM_INFINITY}) = 0

Edit No. 4: /etc/security/limits.conf with comments removed

*                soft    core            unlimited
*                hard    core            unlimited
@service          hard    nofile          13000
@service          soft    nofile          13000
*                soft    nofile          12000
*                hard    nofile          12000
clk
  • 2,116
  • 1
  • 17
  • 25
devsda
  • 427
  • 3
  • 10
  • 19
  • Now, what's `grep execve rsh.strace.31472`? Is it `rshd`? Is it opening a `limits.conf` and `pam_limits.so` just before by any chance? – Stéphane Chazelas Mar 19 '13 at 10:13
  • Yes, it is rshd. – devsda Mar 19 '13 at 10:16
  • In /etc/security/limits.conf, it has 12000 value, and when I do `ulimit -n`, it shows 12000. But here how it sets 1024. From where it get this value ? Weird behaviour. – devsda Mar 19 '13 at 10:19
  • `14:22:42.961881 open("/etc/passwd", O_RDONLY) = 0` `14:22:42.962447 open("/proc/sys/kernel/ngroups_max", O_RDONLY) = 0` `14:22:42.963199 open("/etc/group", O_RDONLY) = 0` `14:22:42.964310 open("/etc/hosts.allow", O_RDONLY) = 0` `14:22:42.964785 open("/etc/hosts.deny", O_RDONLY) = 0` These files are open before `setrlimit` syscall – devsda Mar 19 '13 at 10:26
  • @StephaneChazelas `rsh.strace.31472` is related with `rshd` and `rsh.strace.31474` is related with `/bin/bash`. I checked this by running `grep execve rsh.strace.31472.` and `grep execve rsh.strace.31474`. – devsda Mar 19 '13 at 10:38
  • Can you post the full content of your limits.conf? Do you have a `/etc/security/limits.d` directory with further configuration? – Stéphane Chazelas Mar 19 '13 at 10:45
  • @StephaneChazelas See edit no. 4, it shows `vim /etc/security/limits.conf` and `/etc/security/limits.d` does not contain any file. – devsda Mar 19 '13 at 10:51
  • @StephaneChazelas My machine has user name `service` under groupname `service`. – devsda Mar 19 '13 at 10:56
  • BTW, your strace output in "edit 2" above is of `bash -c ulimit -n`, which is the same as `bash -c ulimit`. You'd need `rsh localhost "strace bash -c 'ulimit -n'"`. – Stéphane Chazelas Mar 19 '13 at 10:59
  • @StephaneChazelas But Edit no 2 gives `unlimited`, but it expected that it gives `13000`, from `service` user. – devsda Mar 19 '13 at 11:03
  • @StephaneChazelas We are very close to our result. Can we do a discussion on chat ? Please. – devsda Mar 19 '13 at 11:04
  • let us [continue this discussion in chat](http://chat.stackexchange.com/rooms/7984/discussion-between-stephane-chazelas-and-jhamb) – Stéphane Chazelas Mar 19 '13 at 11:04
  • @StephaneChazelas kindly see one message leave by me for you. Please read that, and if possible give some reply. Thanks – devsda Mar 20 '13 at 18:56
  • @StephaneChazelas Can you please guide me to solve one bug? Can you come on chat please ? – devsda Mar 21 '13 at 07:31
  • @StephaneChazelas Two days ago, you helped me to make a wrapper function. Thats fine, and that is working properly. But when I saw my rsh code and standard rsh code, that is totally same. PAM module calling is also same. Both uses equal number of calling of PAM. In short, my rsh is derived from standard rsh, with some features added in it. Then why , my rsh not loads PAM modules. Why ? and I think my MCONFIG is not loaded during when I run `make`. Help me to add these `MRULES` , MCONFIG.in` , `configure` in my rsh make. Please. I am waiting for your reply. I need your expert guidance here. – devsda Mar 22 '13 at 05:32
  • @StephaneChazelas Help me please in correcting the code. I want to run code that uses PAM modules and limits.conf. I read both the codes. Both are totally same. Can you please tell me how can I debug. Any library/Debugger/tool ? – devsda Mar 24 '13 at 08:50
  • @StephaneChazelas Please give answer of this link, http://unix.stackexchange.com/questions/69044/why-rsh-not-opens-and-reads-pam-modules-and-limits-conf . This makes my doubts clear. So guide me how to proceed in this problem. – devsda Mar 25 '13 at 08:48
  • I (or anybody here) am not a hotline, ask your question on a SE site, clarify the questions, offer bounties if the answers don't suit you... – Stéphane Chazelas Mar 25 '13 at 10:28
  • @StephaneChazelas Ohk, that question is fresh , and related to this question, and I accepted your last answer. That's why I gave link of another question to you. That question is the extended version of this question , for that we did a chat discussion – devsda Mar 25 '13 at 10:36
  • @StephaneChazelas I will definitely give you my hard-earned 100 points. If you solve my problem. Its a gentleman promise. Now I think you will probably solve my problem. But now I am not start bounty, as that question is fresh. It takes two days to start a bounty. So, can we start a discussion on my above linked question. I will give you a (10(up-vote) + 15(accepted) + 100(hard-earned)) points, definitely. – devsda Mar 25 '13 at 10:43
  • @StephaneChazelas I tried a lot, but till now I am not able to resolve this problem. I am not able to load PAM modules in rshd.c. I also started a bounty on one of the related question, http://stackoverflow.com/questions/15614823/pam-appl-h-and-pam-misc-h-missing-in-rshd-c-source-code Please help me. Its a humble request to you. I also posted one more question http://unix.stackexchange.com/questions/71783/how-can-i-add-pam-functionality-in-netkit-rsh-0-17 . I will give my some of the reputation to you please help me. – devsda Apr 09 '13 at 09:57

3 Answers3

2

You'll need to identify what server process on the server runs the rsh aka shell service. Traditionally, it's started by the inetd or xinetd meta-daemon which listens on the shell TCP port (514) and runs the rshd command upon an incoming connection.

lsof -i tcp:shell

(as root) Will tell you what process is listening on that port.

You can strace that with:

strace -tt -ff -o rsh.strace -p "the-PID"

The -ff option follows forks and creates one log file per process which makes it easier to read.

The log files will be named rsh.strace.<pid> where <pid> is the process ID of the corresponding process. xinetd will spawn a new process to run the rshd server, which itself may spawn another process to run the login shell of the user which itself will possibly spawn several processes when interpreting ~/.bashrc (yes bash (if it's the user's login shell), does interpret ~/.bashrc when run over rsh even if it's not a login shell).

Then, you can look in there who does the setrlimit with:

grep setrlimit rsh.strace.*

Once you've identified the process. You can do a

grep execve rsh.strace.<that-pid>

To see if that process executed a command before doing that setrlimit which will tell you what command did the ulimit. If that process didn't do the execve then its parent or grandparent did. You can find out the parent, by checking which process did the fork/clone that resulted in that <pid> like:

grep -E '(clone|fork).*= <that-pid>' rsh.strace.*

If the process is inetd/xinetd and inetd is serving a lot of other services beside shell, alternatively you could change its configuration to run strace -tt -ff -o /var/log/rsh.strace in.rshd instead of in.rshd for the shell service, or make a wrapper script around in.rshd to call the real in.rshd under strace.

Now the two likely things that set the ulimit are either PAM (via the pam_limits module and /etc/security/limits.conf), and the remote user's login shell startup scripts.

In the latter case, instead of stracing rshd, you could enable shell tracing in the login shell. For instance, if the remote user's login shell is bash or sh, sh being a symlink to bash, you can change /usr/sbin/in.rshd (or whatever the location of the rsh daemon command is) to a wrapper script that does:

#! /bin/sh -
exec /usr/bin/env SHELLOPTS=xtrace "$0.bin" "$@"

After having renamed it to in.rshd.bin.

Stéphane Chazelas
  • 522,931
  • 91
  • 1,010
  • 1,501
  • i followed your instructions, run `strace -tt -ff -o rsh.strace -p "the-PID"` command, and it makes 44 files having name `rsh.strace.*`, where * is integer number. But after that I didn't understand what you said. please make me understand all the things step by step. I will be very thankful to you. If you have time then, can you guide me on chat. – devsda Mar 19 '13 at 09:03
  • @jhamb, those are the system call made by each process spawned by that `the-PID` and its children (the number is the pid). There's one for `the-PID`, one of them is probably for the process that runs the login shell of the user, one for every process spawned to run the commands specified in the the startup files (`~/.bashrc` or other) one for the command you run over rsh. Now you can do a `grep -e ulimit -e setrlimit rsh.strace*` to find out where the `ulimit` is done. – Stéphane Chazelas Mar 19 '13 at 10:06
  • I added Edit no. 3, that shows output of `grep -e ulimit -e setrlimit rsh.strace*`. Please xplain 3rd and 4th paragraph. Now what can I do to solve my problem. – devsda Mar 19 '13 at 10:14
  • Very very thanks to you to guide me to solve this problem, and give your precious time to me. I want to give my 50 reputation to you. I know it is very small for such a geek like you. Is there any way to give points ? – devsda Mar 19 '13 at 14:34
1

I don't have that much experience with rsh, but this is how I would solve it using strace.

You can strace a running process using the -p flag. So something like this

linux$ strace -p $(pidof rshd) -o logfile.txt

Either that or you can modify the script that starts the rsh deamon to use strace. It might be good to use strace -o logfile for this, since otherwise the output might be hidden by the scripts starting the rsh daemon.

Kotte
  • 2,467
  • 22
  • 26
  • I know this command, but when I run `pidof rshd`, it shows blank. Why ? I tried this command earlier. How can I start rshd to take this in running process. – devsda Mar 19 '13 at 07:21
  • This command must be running on the server machine. – Kotte Mar 19 '13 at 07:26
  • I mentioned in my question that I have only one machine , server and client on same machine. How to check if server run or not? If `rah localhost pwd` runs , then it means rsh server is running. If I am wrong at any point , please correct me. – devsda Mar 19 '13 at 07:31
  • 1
    Could be that this service is provieded by xinetd. Try checking the content of `/etc/xinted.d/` or running `sudo lsof -i :514` to see which process provides the shell. – Kotte Mar 19 '13 at 07:38
  • Check Edit No. 1, it gives answer of both command. – devsda Mar 19 '13 at 08:18
  • I solved my problem. But thanks for your efforts, and taking time for me. – devsda Mar 20 '13 at 04:50
0

Very easy: What rsh machine command does is to launch command on machine. I.e., if you do rsh localhost ulimit -u, what happens is that the command ulimit -u runs on localhost (i.e., on this same machine). That rsh is involved in calling it is completely irrelevant. If you want to know what happens there, just look at what ulimit -u does.

You can analyze rshd until you are blue in the face, it won't ever do anything but (1) get the connection and check it is allowed, (2) collect the command to run, (3) fork/exec to run the command, connected to send the output back. In particular, you won't see any ulimit frobbing that way.

vonbrand
  • 18,156
  • 2
  • 37
  • 59