#include <sys/ioctl.h>
#include <arpa/inet.h>
#include <net/if_arp.h>
+#include <pwd.h>
+#include <grp.h>
static void usage(void);
char *lsb_release = NULL;
int smart = 15;
int receiveonly = 0;
+ int ctl;
+
+ /* Non privileged user */
+ struct passwd *user;
+ struct group *group;
+ uid_t uid;
+ gid_t gid;
saved_argv = argv;
log_init(debug, __progname);
tzset(); /* Get timezone info before chroot */
+ /* Grab uid and gid to use for priv sep */
+ if ((user = getpwnam(PRIVSEP_USER)) == NULL)
+ fatal("no " PRIVSEP_USER " user for privilege separation");
+ uid = user->pw_uid;
+ if ((group = getgrnam(PRIVSEP_GROUP)) == NULL)
+ fatal("no " PRIVSEP_GROUP " group for privilege separation");
+ gid = group->gr_gid;
+
+ /* Create and setup socket */
+ if ((ctl = ctl_create(LLDPD_CTL_SOCKET)) == -1) {
+ LLOG_WARN ("unable to create control socket");
+ LLOG_WARNX("If another instance is running, please stop it.");
+ LLOG_WARNX("Otherwise, remove " LLDPD_CTL_SOCKET);
+ fatalx("Giving up");
+ }
+ if (chown(LLDPD_CTL_SOCKET, uid, gid) == -1)
+ LLOG_WARN("unable to chown control socket");
+ if (chmod(LLDPD_CTL_SOCKET,
+ S_IRUSR | S_IWUSR | S_IXUSR |
+ S_IRGRP | S_IWGRP | S_IXGRP) == -1)
+ LLOG_WARN("unable to chmod control socket");
+
+ /* Detach if needed */
if (!debug) {
int pid;
char *spid;
lsb_release = lldpd_get_lsb_release();
}
- priv_init(PRIVSEP_CHROOT);
+ priv_init(PRIVSEP_CHROOT, ctl, uid, gid);
/* Initialization of global configuration */
if ((cfg = (struct lldpd *)
calloc(1, sizeof(struct lldpd))) == NULL)
fatal(NULL);
+ cfg->g_ctl = ctl;
cfg->g_mgmt_pattern = mgmtp;
cfg->g_cid_pattern = cidp;
cfg->g_interfaces = interfaces;
TAILQ_INSERT_TAIL(&cfg->g_chassis, lchassis, c_entries);
lchassis->c_refcount++; /* We should always keep a reference to local chassis */
- /* Create socket */
- if ((cfg->g_ctl = priv_ctl_create()) == -1)
- fatalx("unable to create control socket " LLDPD_CTL_SOCKET);
-
/* Main loop */
levent_loop(cfg);
lldpd_exit(cfg);
#include <sys/un.h>
#include <regex.h>
#include <fcntl.h>
-#include <pwd.h>
#include <grp.h>
#include <sys/utsname.h>
#include <sys/ioctl.h>
enum {
PRIV_PING,
- PRIV_CREATE_CTL_SOCKET,
PRIV_DELETE_CTL_SOCKET,
PRIV_GET_HOSTNAME,
PRIV_OPEN,
static int monitored = -1; /* Child */
static int sock = -1;
-/* UID/GID of unprivileged user */
-static gid_t gid = 0;
-static uid_t uid = 0;
-
/* Proxies */
static void
LLOG_DEBUG("monitor ready");
}
-/* Proxy for ctl_create, no argument since this is the monitor that decides the
- * location of the socket */
-int
-priv_ctl_create()
-{
- int cmd, rc;
- cmd = PRIV_CREATE_CTL_SOCKET;
- must_write(remote, &cmd, sizeof(int));
- must_read(remote, &rc, sizeof(int));
- if (rc == -1)
- return -1;
- return receive_fd(remote);
-}
-
/* Proxy for ctl_cleanup */
void
priv_ctl_cleanup()
must_write(remote, &rc, sizeof(int));
}
-static void
-asroot_ctl_create()
-{
- int rc;
- if ((rc = ctl_create(LLDPD_CTL_SOCKET)) == -1) {
- LLOG_WARN("[priv]: unable to create control socket");
- LLOG_WARNX("[priv]: If another instance is running, please stop it.");
- LLOG_WARNX("[priv]: Otherwise, remove " LLDPD_CTL_SOCKET);
- must_write(remote, &rc, sizeof(int));
- return;
- }
- if (chown(LLDPD_CTL_SOCKET, uid, gid) == -1)
- LLOG_WARN("[priv]: unable to chown control socket");
- if (chmod(LLDPD_CTL_SOCKET,
- S_IRUSR | S_IWUSR | S_IXUSR |
- S_IRGRP | S_IWGRP | S_IXGRP) == -1)
- LLOG_WARN("[priv]: unable to chmod control socket");
- must_write(remote, &rc, sizeof(int));
- send_fd(remote, rc);
- close(rc);
-}
-
static void
asroot_ctl_cleanup()
{
static struct dispatch_actions actions[] = {
{PRIV_PING, asroot_ping},
- {PRIV_CREATE_CTL_SOCKET, asroot_ctl_create},
{PRIV_DELETE_CTL_SOCKET, asroot_ctl_cleanup},
{PRIV_GET_HOSTNAME, asroot_gethostbyname},
{PRIV_OPEN, asroot_open},
/* Initialization */
void
-priv_init(char *chrootdir)
+priv_init(char *chrootdir, int ctl, uid_t uid, gid_t gid)
{
+
int pair[2];
- struct passwd *user;
- struct group *group;
gid_t gidset[1];
int status;
if (socketpair(AF_LOCAL, SOCK_DGRAM, PF_UNSPEC, pair) < 0)
fatal("[priv]: unable to create socket pair for privilege separation");
- /* Get users */
- if ((user = getpwnam(PRIVSEP_USER)) == NULL)
- fatal("[priv]: no " PRIVSEP_USER " user for privilege separation");
- uid = user->pw_uid;
- if ((group = getgrnam(PRIVSEP_GROUP)) == NULL)
- fatal("[priv]: no " PRIVSEP_GROUP " group for privilege separation");
- gid = group->gr_gid;
-
/* Spawn off monitor */
if ((monitored = fork()) < 0)
fatal("[priv]: unable to fork monitor");
break;
default:
/* We are in the monitor */
+ if (ctl != -1) close(ctl);
remote = pair[1];
close(pair[0]);
if (atexit(priv_exit) != 0)