Example #1
0
/**
 * close_context
 *
 * Arguments: <context_id>
 *
 * Close the context's file descriptor, remove it from the global list, and
 * free the context data structures.
 **/
static int close_context(int argc, char **argv)
{
	struct context *ctx;
	struct event_set *evt, *next_evt;
	int ctx_id;

	ctx_id = strtoul(argv[1], NULL, 0);
	if (ctx_id <= 0) {
		LOG_ERROR("context ID must be a positive integer.");
		return EINVAL;
	}

	ctx = find_context(ctx_id);
	if (!ctx) {
		LOG_ERROR("Can't find context with ID %d.", ctx_id);
		return EINVAL;
	}

	/* There's no perfmon system-call to delete a context. We simply call
	 * close on the file handle.
	 */
	close(ctx->fd);
	remove_context(ctx);

	for (evt = ctx->event_sets; evt; evt = next_evt) {
		next_evt = evt->next;
		free(evt);
	}
	free(ctx);

	LOG_INFO("Closed and freed context %d.", ctx_id);

	return 0;
}
Example #2
0
static void TCPCOMM_detachThread(int socket, CONST CMPIBroker * broker,
                                 CONST CMPIContext * context)
{
    CMPIStatus rc;
    CMPIData ctxid = CMGetContextEntry(context, RCMPI_CTX_ID, NULL);
    CONST CMPIContext *ctx = get_context(ctxid.value.uint32);
    remove_context(ctxid.value.uint32);
    rc = CBDetachThread(broker, ctx);
    (__sft)->serialize_CMPIStatus(socket, &rc);
}
/* Process the raw netlink message and dispatch to helper functions
 * accordingly */
static void
receive_netlink_message (GUPnPLinuxContextManager *self, GError **error)
{
        static char buf[4096];
        static const int bufsize = 4096;

        gssize len;
        GError *inner_error = NULL;
        struct nlmsghdr *header = (struct nlmsghdr *) buf;
        struct ifinfomsg *ifi;
        struct ifaddrmsg *ifa;


        len = g_socket_receive (self->priv->netlink_socket,
                                buf,
                                bufsize,
                                NULL,
                                &inner_error);
        if (len == -1) {
                if (inner_error->code != G_IO_ERROR_WOULD_BLOCK)
                        g_warning ("Error receiving netlink message: %s",
                                   inner_error->message);
                g_propagate_error (error, inner_error);

                return;
        }

        for (;NLMSG_IS_VALID (header, len); header = NLMSG_NEXT (header,len)) {
                switch (header->nlmsg_type) {
                        /* RTM_NEWADDR and RTM_DELADDR are sent on real address
                         * changes.
                         * RTM_NEWLINK is sent on varous occations:
                         *  - Creation of a new device
                         *  - Device goes up/down
                         *  - Wireless status changes
                         * RTM_DELLINK is sent only if device is removed, like
                         * openvpn --rmtun /dev/tun0, NOT on ifconfig down. */
                        case RTM_NEWADDR:
                            {
                                char *label = NULL;

                                ifa = NLMSG_DATA (header);
                                extract_info (header, &label);
                                create_context (self, label, ifa);
                                g_free (label);
                            }
                            break;
                        case RTM_DELADDR:
                            {
                                char *label = NULL;

                                ifa = NLMSG_DATA (header);
                                extract_info (header, &label);
                                remove_context (self, label, ifa);
                                g_free (label);
                            }
                            break;
                        case RTM_NEWLINK:
                                ifi = NLMSG_DATA (header);

                                /* Check if wireless is up for chit-chat */
                                if (is_wireless_status_message (header))
                                        continue;
                                handle_device_status_change (self, ifi);
                                break;
                        case RTM_DELLINK:
                                ifi = NLMSG_DATA (header);
                                remove_device (self, ifi);
                                break;
                        case NLMSG_ERROR:
                                break;
                        default:
                                break;
                }
        }
}
Example #4
0
int
main(int argc, char *argv[])
{
	int			i;
	int			rc;
	pid_t			pid, retpid;
	int			status;
	char			*program;
	char			*pdesc;
	char			*pc;
	int			pw_pipe;
	int			expire_delta;
	int			refresh_time;


	/* call me redundant, but it's satisfying to see this */
	handler_refreshed_context = 0;
	have_login_context = 0;
	pid = 0;

	/*test for real deal or just version and exit*/

	PRINT_VERSION_AND_EXIT(argc, argv);

	if (argc < 3) {
		fprintf(stderr, "usage: %s user program [arg(s)]\n", argv[0]);
		fprintf(stderr, "       %s --version\n", argv[0]);
		exit(254);
	}

	/* In the event we inherited creds from the parent, ignore them. */
	if (getenv("KRB5CCNAME") != NULL) {
		unsetenv("KRB5CCNAME");
	}

	/* read password from descriptor, close descriptor */

	if ((pdesc = getenv("PBS_PWPIPE")) == NULL) {
		fprintf(stderr, "PBS_PWPIPE not in the environment\n");
		exit  (254);
	}
	pw_pipe = atoi(pdesc);
	if (errno != 0) {
		fprintf(stderr, "Value of PBS_PWPIPE is bad\n");
		exit  (254);
	}
	for (;;) {
		i = read(pw_pipe, &tmp_passwd[0], sec_passwd_str_max_len);
		if (i == -1 && errno == EINTR)
			continue;
		break;
	}
	close(pw_pipe);

	username = argv[1];
	program = strdup(argv[2]);

	/* when execv-ing a shell interpreter, cause it to be a login shell */
	if (argc == 3) {
		if (pc = strrchr(argv[2], (int)'/')) {
			*pc = '-';
			argv[2] = pc;
		}
	}

	/* Attempt to establish login context for user */
	if (rc=establish_login_context(username)) {
		have_login_context = 0;
	} else {
		have_login_context = 1;
		rc=252;
	}

	/*
	 * If we have a login context, fork the child that will become
	 * the job. The parent sticks around to refresh the context
	 * periodically.
	 *
	 * If we don't have a login context, exec the job over ourself.
	 */
	if (have_login_context) {
		if ((pid = fork()) == -1) {
			perror("fork");
			(void)remove_context();
			exit(254);
		}
	}

	if (pid == 0) { /* exec the program */
		if (execv(program, &argv[2]) == -1) {
			/* execv system call failed */
			perror("execv");
			fprintf(stderr, "pbs_dcelogin: execv system call failed\n");
			exit(rc);
		}
		/* child should never get here */
		exit(99);
	}

	/*
	 * go into a loop which will every so often refresh the
	 * the DCE login context while it waits for the child to terminate
	 */

	refresh_time = compute_refresh_time(lcon);
	for (;;) {
		if ((retpid = waitpid(pid, &status, WNOHANG)) == -1) {
			perror("pbs_dcelogin: waitpid");
			break;
		}
		else if (retpid > 0)		/* child finished */
			break;

		/* see if it is time to refresh */
		if (0 < refresh_time && refresh_time <= time(NULL))
			refresh_time = do_refresh(lcon);
		sleep(5);
	}

	/* after removing any created DCE login context and credential cache
	 * files, pass back the exit status of the job
	 */

	(void)remove_context();

	if (retpid == pid) {
		if (WIFEXITED(status)) {
			exit(WEXITSTATUS(status));
		} else if (WIFSIGNALED(status)) {
			exit(WTERMSIG(status));
		} else if (WIFSTOPPED(status)) {
			exit(WSTOPSIG(status));
		} else {
			exit(253);
		}
	} else {
		exit(254);
	}
}