On Tue, Jul 30, 2013 at 03:55:45PM -0400, dwalsh(a)redhat.com wrote:
From: Dan Walsh <dwalsh(a)redhat.com>
Openshift wants to have their gears stuck into a container when they login
to the system. virt-login-shell will join a running gear with the username of
the person running it, or attempt to start the container if it is not running.
(Currently containers do not exist if they are not running, so I can not test
this feature. But the code is there).
This tool needs to be setuid since joining a container (nsjoin) requires privs.
The root user is not allowed to execute this command. When this tool is
run by a normal user it will only join the "users" container.
Only users who are listed as valid_users in /etc/libvirt/virt-login-shell.conf
are allowed to join containers using this tool. By default no users are allowed.
---
+static ssize_t nfdlist = 0;
+static int *fdlist = NULL;
+static const char *conf_file = SYSCONFDIR "/libvirt/virt-login-shell.conf";
+
+static void virLoginShellFini(virConnectPtr conn, virDomainPtr dom)
+{
+ size_t i;
+
+ for (i = 0; i < nfdlist; i++)
+ VIR_FORCE_CLOSE(fdlist[i]);
+ VIR_FREE(fdlist);
+ nfdlist = 0;
+ if (dom)
+ virDomainFree(dom);
+ if (conn)
+ virConnectClose(conn);
There are lots of tabs used for indent here and later in this
file. Please check with 'make syntax-check'.
+static int virLoginShellAllowedUser(virConfPtr conf,
+ uid_t uid,
+ gid_t gid,
+ const char *name)
+{
+ virConfValuePtr p;
+ int ret = -1;
+ char *ptr = NULL;
+ size_t i;
+ gid_t *groups = NULL;
+ char *gname = NULL;
+
+ p = virConfGetValue(conf, "allowed_users");
+ if (p && p->type == VIR_CONF_LIST) {
+ virConfValuePtr pp;
+
+ /* Calc length and check items */
+ for (pp = p->list; pp; pp = pp->next) {
+ if (pp->type != VIR_CONF_STRING) {
+ virReportSystemError(EINVAL, "%s", _("shell must be a list of
strings\n"));
+ goto cleanup;
+ } else {
+ /*
+ If string begins with a % this indicates a linux group.
+ Check to see if the user is in the Linux Group.
+ */
+ if (pp->str[0] == '%') {
+ ptr = &pp->str[1];
+ if (!ptr)
+ continue;
+ if (virGetGroupList(uid, gid, &groups) < 0) {
+ goto cleanup;
+ }
+ for (i = 0; groups[i]; i++) {
+ if (!(gname = virGetGroupName(groups[i])))
+ continue;
+ if (fnmatch(ptr, gname, 0) == 0) {
+ ret = 0;
+ goto cleanup;
+ }
+ VIR_FREE(gname);
+ }
+ VIR_FREE(groups);
+ continue;
+ }
+ if (fnmatch(pp->str, name, 0) == 0) {
+ ret = 0;
+ goto cleanup;
+ }
+ }
+ }
+ }
+ virReportSystemError(EPERM, _("%s not listed as an allowed_users in %s"),
name, conf_file);
+ errno = EPERM;
No need to set errno if you using virReportSystemError().
+cleanup:
+ VIR_FREE(gname);
+ VIR_FREE(groups);
+ return ret;
+}
+
+int
+main(int argc, char **argv)
+{
+
+ struct option opt[] = {
+ {"help", no_argument, NULL, 'h'},
+ {NULL, 0, NULL, 0}
+ };
+ virReportSystemError(1, "%s %d %s", "Test1", argc, argv[0]);
Accidental debug line left in I presume
+ if (virInitialize() < 0) {
+ fprintf(stderr, _("Failed to initialize libvirt Error Handling"));
+ return EXIT_FAILURE;
+ }
+ virReportSystemError(EINVAL, "%s", "Test2");
And here
+
+ if (virErrorInitialize() < 0) {
+ fprintf(stderr, _("Failed to initialize libvirt Error Handling"));
+ return EXIT_FAILURE;
+ }
Actually no need to call virErrorInitialize() - virInitialize
takes care of that for you
+ if (uid == 0) {
+ virReportSystemError(EPERM, _("%s must be run by non root users"),
progname);
+
+ errno = EPERM;
No need to set errno.
+ if (virFork(&cpid) < 0)
+ goto cleanup;
+
+ if (cpid == 0) {
+ gid_t *groups = NULL;
+ int ngroups;
+ pid_t ccpid;
+
+ /* Fork once because we don't want to affect
+ * virt-login-shell's namespace itself
+ */
+ if (virSetUIDGID(0, 0, NULL, 0) < 0)
+ return EXIT_FAILURE;
+
+ if (virDomainLxcEnterSecurityLabel(secmodel,
+ seclabel,
+ NULL,
+ 0) < 0)
+ return EXIT_FAILURE;
+
+ if (nfdlist > 0) {
+ if (virDomainLxcEnterNamespace(dom,
+ nfdlist,
+ fdlist,
+ NULL,
+ NULL,
+ 0) < 0)
+ return EXIT_FAILURE;
+ }
+
+ if ((ngroups = virGetGroupList(uid, gid, &groups)) < 0)
+ return EXIT_FAILURE;
virGetGroupList isn't safe to call after fork(). Need to
move it earlier in this function.
+
+ ret = virSetUIDGID(uid, gid, groups, ngroups);
+ VIR_FREE(groups);
+ if (ret < 0)
+ return EXIT_FAILURE;
+
+ if (virFork(&ccpid) < 0)
+ return EXIT_FAILURE;
+
+ if (ccpid == 0) {
+ if (chdir(homedir) < 0) {
+ virReportSystemError(errno, _("Unable chdir(%s)"), homedir);
+ return EXIT_FAILURE;
+ }
+ if (execv(shargv[0], (char *const*) shargv) < 0) {
+ virReportSystemError(errno, _("Unable exec shell %s"), shargv[0]);
+ return -errno;
+ }
+ }
+ return virProcessWait(ccpid, &status2);
+ }
+ ret = virProcessWait(cpid, &status);
+
Regards,
Daniel
--
|:
http://berrange.com -o-
http://www.flickr.com/photos/dberrange/ :|
|:
http://libvirt.org -o-
http://virt-manager.org :|
|:
http://autobuild.org -o-
http://search.cpan.org/~danberr/ :|
|:
http://entangle-photo.org -o-
http://live.gnome.org/gtk-vnc :|