Je veux savoir comment rsh exécute n'importe quelle commande. J'utilise le paquet netkit-rsh-0.17. Mon système d'exploitation est centOS.Explique comment fonctionne la fonction doit() dans rshd.c
Dans le répertoire rshd, rshd.c
exécute la tâche pour exécuter toute commande sur le serveur. Dans ce fichier, doit()
est la fonction principale qui effectue toute la tâche.
Questions,
- Qu'est-ce
pwd->pw_dir
,pwd->pw_uid
,pwd->pw_shell
moyens dans ce code? - Ce que
pv
fait dans ce.
Expliquez-moi en utilisant la commande rsh localhost ulimit -n
.
Doït()
static void
doit(struct sockaddr_in *fromp)
{
char cmdbuf[ARG_MAX+1];
const char *theshell, *shellname;
char locuser[16], remuser[16];
struct passwd *pwd;
int sock = -1;
const char *hostname;
u_short port;
int pv[2], pid, ifd;
signal(SIGINT, SIG_DFL);
signal(SIGQUIT, SIG_DFL);
signal(SIGTERM, SIG_DFL);
alarm(60);
port = getint();
alarm(0);
if (port != 0) {
int lport = IPPORT_RESERVED - 1;
sock = rresvport(&lport);
if (sock < 0) {
syslog(LOG_ERR, "can't get stderr port: %m");
exit(1);
}
if (port >= IPPORT_RESERVED) {
syslog(LOG_ERR, "2nd port not reserved\n");
exit(1);
}
fromp->sin_port = htons(port);
if (connect(sock, (struct sockaddr *)fromp,
sizeof(*fromp)) < 0) {
syslog(LOG_INFO, "connect second port: %m");
exit(1);
}
}
#if 0
/* We're running from inetd; socket is already on 0, 1, 2 */
dup2(f, 0);
dup2(f, 1);
dup2(f, 2);
#endif
getstr(remuser, sizeof(remuser), "remuser");
getstr(locuser, sizeof(locuser), "locuser");
getstr(cmdbuf, sizeof(cmdbuf), "command");
if (!strcmp(locuser, "root")) paranoid = 1;
hostname = findhostname(fromp, remuser, locuser, cmdbuf);
setpwent();
pwd = doauth(remuser, hostname, locuser);
if (pwd == NULL) {
fail("Permission denied.\n",
remuser, hostname, locuser, cmdbuf);
}
if (chdir(pwd->pw_dir) < 0) {
chdir("/");
/*
* error("No remote directory.\n");
* exit(1);
*/
}
if (pwd->pw_uid != 0 && !access(_PATH_NOLOGIN, F_OK)) {
error("Logins currently disabled.\n");
exit(1);
}
(void) write(2, "\0", 1);
sent_null = 1;
if (port) {
if (pipe(pv) < 0) {
error("Can't make pipe.\n");
exit(1);
}
pid = fork();
if (pid == -1) {
error("Can't fork; try again.\n");
exit(1);
}
if (pid) {
close(0);
close(1);
close(2);
close(pv[1]);
stderr_parent(sock, pv[0], pid);
/* NOTREACHED */
}
setpgrp();
close(sock);
close(pv[0]);
dup2(pv[1], 2);
close(pv[1]);
}
theshell = pwd->pw_shell;
if (!theshell || !*theshell) {
/* shouldn't we deny access? */
theshell = _PATH_BSHELL;
}
#if BSD > 43
if (setlogin(pwd->pw_name) < 0) {
syslog(LOG_ERR, "setlogin() failed: %m");
}
#endif
#ifndef USE_PAM
/* if PAM, already done */
if (setgid(pwd->pw_gid)) {
syslog(LOG_ERR, "setgid: %m");
exit(1);
}
if (initgroups(pwd->pw_name, pwd->pw_gid)) {
syslog(LOG_ERR, "initgroups: %m");
exit(1);
}
#endif
if (setuid(pwd->pw_uid)) {
syslog(LOG_ERR, "setuid: %m");
exit(1);
}
environ = envinit;
strncat(homedir, pwd->pw_dir, sizeof(homedir)-6);
homedir[sizeof(homedir)-1] = 0;
strcat(path, _PATH_DEFPATH);
strncat(shell, theshell, sizeof(shell)-7);
shell[sizeof(shell)-1] = 0;
strncat(username, pwd->pw_name, sizeof(username)-6);
username[sizeof(username)-1] = 0;
shellname = strrchr(theshell, '/');
if (shellname) shellname++;
else shellname = theshell;
endpwent();
if (paranoid) {
syslog(LOG_INFO|LOG_AUTH, "%[email protected]%s as %s: cmd='%s'",
remuser, hostname, locuser, cmdbuf);
}
/*
* Close all fds, in case libc has left fun stuff like
* /etc/shadow open.
*/
for (ifd = getdtablesize()-1; ifd > 2; ifd--) close(ifd);
execl(theshell, shellname, "-c", cmdbuf, 0);
perror(theshell);
exit(1);
}
Lisez la page de manuel sur 'exec (3)'. Il remplace le programme en cours d'exécution par un nouveau. – vonbrand
J'ai lu cela, mais comment cela peut-il effectuer toute la tâche dans la fonction ci-dessus en utilisant la commande ci-dessus écrite en question, s'il vous plaît. – devsda
Il s'agit d'une question de programmation système de première année. Toutes les fonctions du code ci-dessus ont des pages 'man'. – millimoose