Sisyphus repository
Last update: 1 october 2023 | SRPMs: 18631 | Visits: 37407138
en ru br
ALT Linux repos
S:0.2-alt1
5.0: 0.1-alt2
4.1: 0.1-alt2
4.0: 0.1-alt2
3.0: 0.1-alt1

Group :: System/Servers
RPM: cmdproxyd

 Main   Changelog   Spec   Patches   Sources   Download   Gear   Bugs and FR  Repocop 

cmdproxyd-0.2/000075500000000000000000000000001213375555700133775ustar00rootroot00000000000000cmdproxyd-0.2/.gitignore000064400000000000000000000000211213375555700153600ustar00rootroot00000000000000cmdproxyd
*.[do]
cmdproxyd-0.2/Makefile000064400000000000000000000031541213375555700150420ustar00rootroot00000000000000#
# Copyright (C) 2004 Dmitry V. Levin <ldv@altlinux.org>
#
# Makefile for the cmdproxyd project.
#
# This file is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#

PROJECT = cmdproxyd
TARGETS = $(PROJECT)

sbindir = /usr/sbin
DESTDIR =

MKDIR_P = mkdir -p
INSTALL = install
CFLAGS = -pipe -Wall -Werror -W -O2

SRC = cmdproxyd.c
OBJ = $(SRC:.c=.o)
DEP = $(SRC:.c=.d)

.PHONY: all install clean indent

all: $(TARGETS)

$(PROJECT): $(OBJ)
$(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -o $@

install: all
$(MKDIR_P) -m755 $(DESTDIR)$(sbindir)
$(INSTALL) -p -m755 cmdproxyd $(DESTDIR)$(sbindir)/

clean:
$(RM) $(TARGETS) $(DEP) $(OBJ) core *~

indent:
indent *.c

# We need dependencies only if goal isn't "indent" or "clean".
ifneq ($(MAKECMDGOALS),indent)
ifneq ($(MAKECMDGOALS),clean)

%.d: %.c
@echo Making dependences for $<
@$(SHELL) -ec "$(CC) -MM $(CPPFLAGS) $< | sed -e 's|\($*\)\.o[ :]*|\1.o $@ : |g' > $@; [ -s $@ ] || $(RM) $@"

ifneq ($(DEP),)
-include $(DEP)
endif

endif # clean
endif # indent
cmdproxyd-0.2/cmdproxyd.c000064400000000000000000000123661213375555700155640ustar00rootroot00000000000000
/*
Copyright (C) 2004 Dmitry V. Levin <ldv@altlinux.org>

The command proxy daemon.

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/

#define _GNU_SOURCE

#include <stdio.h>
#include <errno.h>
#include <error.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <syslog.h>
#include <fcntl.h>
#include <pwd.h>
#include <grp.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/un.h>
#include <sys/wait.h>

static void
sigchld_handler( __attribute__ ((unused)) int signo)
{
while (waitpid(-1, 0, WNOHANG) > 0)
;
}

static void __attribute__ ((__noreturn__))
usage(int rc)
{
fprintf((rc == EXIT_SUCCESS) ? stdout : stderr,
"Usage: %s bind_address.. runas program...\n",
program_invocation_short_name);
exit(rc);
}

static int
bind_address(const char *address)
{
struct sockaddr_un sun;

if (strlen(address) >= sizeof(sun))
error(EXIT_FAILURE, EINVAL, "cannot bind socket `%s'",
address);

memset(&sun, 0, sizeof(sun));
sun.sun_family = AF_UNIX;
strcpy(sun.sun_path, address);

int fd = socket(PF_UNIX, SOCK_STREAM, 0);

if (fd < 0)
error(EXIT_FAILURE, errno, "cannot create socket `%s'",
address);

if (bind(fd, (struct sockaddr *) &sun, sizeof(sun)))
{
unlink(address);

if (bind(fd, (struct sockaddr *) &sun, sizeof(sun)))
error(EXIT_FAILURE, errno, "cannot bind socket `%s'",
address);
}

if (chmod(address, 0666))
error(EXIT_FAILURE, errno,
"cannot set permissions of socket `%s'", address);

if (listen(fd, 5) < 0)
error(EXIT_FAILURE, errno, "listen");

int flags;

if ((flags = fcntl(fd, F_GETFD, 0)) == -1)
error(EXIT_FAILURE, errno, "fcntl: F_GETFD");

flags |= FD_CLOEXEC;

if (fcntl(fd, F_SETFD, flags) == -1)
error(EXIT_FAILURE, errno, "fcntl: F_SETFD");

return fd;
}

static void
handle_socket(int fd, const char *address, const char *const *args)
{
struct sockaddr_un sun;

memset(&sun, 0, sizeof(sun));
sun.sun_family = AF_UNIX;
socklen_t sunlen = sizeof(sun);
int accfd = accept(fd, (struct sockaddr *) &sun, &sunlen);

if (accfd < 0)
{
if (errno != EINTR)
{
syslog(LOG_ERR, "accept: %s[%d]: %m", address, fd);
sleep(1);
}
return;
}

struct ucred sucred;
socklen_t credlen = sizeof(struct ucred);

if (getsockopt(accfd, SOL_SOCKET, SO_PEERCRED, &sucred, &credlen))
{
close(accfd);
syslog(LOG_ERR, "getsockopt: SO_PEERCRED: %s[%d]: %m",
address, fd);
sleep(1);
return;
}

struct passwd *pw = getpwuid(sucred.uid);

if (!pw)
{
close(accfd);
syslog(LOG_ERR,
"getsockopt: request from %s, uid=%u, unknown user rejected",
address, sucred.uid);
sleep(1);
return;
}

pid_t pid = fork();

if (pid < 0)
{
close(accfd);
syslog(LOG_ERR, "fork: %m");
sleep(1);
return;
}

if (pid)
{
close(accfd);
return;
}

if (setenv("REMOTE_USER", pw->pw_name, 1))
{
syslog(LOG_ERR, "setenv: %m");
exit(EXIT_FAILURE);
}
dup2(accfd, 0);
close(accfd);
syslog(LOG_INFO, "request from %s by %s(%u), executing %s",
address, pw->pw_name, sucred.uid, args[0]);
execvp(args[0], (char *const *) args);
syslog(LOG_ERR, "execvp: %s: %m", args[0]);
exit(EXIT_FAILURE);
}

int
main(int ac, const char *av[])
{
signal(SIGCHLD, sigchld_handler);

if (ac < 3)
usage(EXIT_FAILURE);

const char *runas = 0;
const char *const *args = 0;
int nsockets = 0;
int i;

for (i = 1; i < ac; ++i)
{
if (runas)
{
args = &av[i];
break;
}

if (av[i][0] == '/')
{
++nsockets;
continue;
}

if (!nsockets)
usage(EXIT_FAILURE);

runas = av[i];
}

if (!nsockets || !runas || !args)
usage(EXIT_FAILURE);

struct passwd *pw = getpwnam(runas);

if (!pw)
error(EXIT_FAILURE, 0, "user `%s' lookup failed", runas);

int sockfd[nsockets];

for (i = 1; i <= nsockets; ++i)
sockfd[i - 1] = bind_address(av[i]);

if (initgroups(runas, pw->pw_gid))
error(EXIT_FAILURE, errno, "initgroups");

if (setgid(pw->pw_gid))
error(EXIT_FAILURE, errno, "setgid");

if (setuid(pw->pw_uid))
error(EXIT_FAILURE, errno, "setuid");

if (daemon(0, 0))
error(EXIT_FAILURE, errno, "daemon");

openlog("cmdproxyd", LOG_PERROR | LOG_PID, LOG_DAEMON);

for (;;)
{
int i, maxfd = 0;
fd_set r;

FD_ZERO(&r);
for (i = 0; i < nsockets; ++i)
{
FD_SET(sockfd[i], &r);
if (sockfd[i] > maxfd)
maxfd = sockfd[i];
}
int rc = select(1 + sockfd[nsockets - 1], &r, 0, 0, 0);

if (rc < 0)
{
if (errno == EINTR)
continue;

syslog(LOG_ERR, "select: %m");
sleep(1);
continue;
}
for (i = 0; i < nsockets; ++i)
if (FD_ISSET(sockfd[i], &r))
handle_socket(sockfd[i], av[1 + i], args);
}
}
cmdproxyd-0.2/cmdproxyd.init000075500000000000000000000021021213375555700162730ustar00rootroot00000000000000#!/bin/sh
#
# chkconfig: - 95 05
# description: \
# The command proxy daemon.
#
# processname: cmdproxyd

WITHOUT_RC_COMPAT=1

# Source function library.
. /etc/init.d/functions

LOCKFILE=/var/lock/subsys/cmdproxyd
RUN_AS=cmdproxyd
BIND_ADDR=
RUN_CMD=
RETVAL=0

# Source config.
SourceIfNotEmpty /etc/sysconfig/cmdproxyd

start()
{
[ -n "$RUN_AS" -a -n "$BIND_ADDR" -a -n "$RUN_CMD" ] || return 0
start_daemon --lockfile "$LOCKFILE" --expect-user "$RUN_AS" -- cmdproxyd $BIND_ADDR "$RUN_AS" $RUN_CMD
RETVAL=$?
return $RETVAL
}

stop()
{
stop_daemon --lockfile "$LOCKFILE" --expect-user "$RUN_AS" cmdproxyd
RETVAL=$?
return $RETVAL
}

restart()
{
stop
start
}

# See how we were called.
case "$1" in
start)
start
;;
stop)
stop
;;
reload|restart)
restart
;;
condstop)
if [ -e "$LOCKFILE" ]; then
stop
fi
;;
condrestart|condreload)
if [ -e "$LOCKFILE" ]; then
restart
fi
;;
status)
status --expect-user "$RUN_AS" cmdproxyd
RETVAL=$?
;;
*)
msg_usage "${0##*/} {start|stop|restart|condstop|condrestart|status}"
RETVAL=1
esac

exit $RETVAL
cmdproxyd-0.2/cmdproxyd.spec000064400000000000000000000017611213375555700162710ustar00rootroot00000000000000Name: cmdproxyd
Version: 0.2
Release: alt1

Summary: A command proxy daemon
License: GPLv2+
Group: System/Servers

Source: %name-%version.tar

PreReq: shadow-utils, service

%description
This is a command proxy daemon.

%prep
%setup

%build
%make_build CFLAGS="%optflags -Werror -W"

%install
%make_install install DESTDIR=%buildroot
install -pD -m755 %name.init %buildroot%_initdir/%name
install -pD -m644 %name.sysconfig %buildroot%_sysconfdir/sysconfig/%name

%post
/usr/sbin/groupadd -r -f %name
/usr/sbin/useradd -r -g %name -d /dev/null -s /dev/null -n %name >/dev/null 2>&1 ||:
%post_service %name

%preun
%preun_service %name

%files
%config %_initdir/*
%config(noreplace) %_sysconfdir/sysconfig/%name
%_sbindir/*

%changelog
* Wed Aug 11 2010 Dmitry V. Levin <ldv@altlinux.org> 0.2-alt1
- Minor fixes and enhancements.

* Tue Apr 10 2007 Dmitry V. Levin <ldv@altlinux.org> 0.1-alt2
- Reduced macro abuse in specfile.

* Wed May 26 2004 Dmitry V. Levin <ldv@altlinux.org> 0.1-alt1
- Initial revision.
cmdproxyd-0.2/cmdproxyd.sysconfig000064400000000000000000000002401213375555700173320ustar00rootroot00000000000000# Username to use for executed commands.
RUN_AS=cmdproxyd

# List of unix domain sockets to bind.
BIND_ADDR=

# Command with its arguments to execute.
RUN_CMD=
 
design & coding: Vladimir Lettiev aka crux © 2004-2005, Andrew Avramenko aka liks © 2007-2008
current maintainer: Michael Shigorin