2011-08-20 Jonathan Nieder <jrnieder@gmail.com>
* lib/Makefile.am: Added lib/spawn.c and lib/spawn.h. * lib/nscd.c, lib/spawn.c, lib/spawn.h: It is not possible to differentiate between an nscd failure, and a failure to execute due to no nscd with posix_spawn. Use our own run_command routine. * src/userdel.c: Use run_command()
This commit is contained in:
		@@ -1,3 +1,11 @@
 | 
			
		||||
2011-08-20  Jonathan Nieder  <jrnieder@gmail.com>
 | 
			
		||||
 | 
			
		||||
	* lib/Makefile.am: Added lib/spawn.c and lib/spawn.h.
 | 
			
		||||
	* lib/nscd.c, lib/spawn.c, lib/spawn.h: It is not possible to
 | 
			
		||||
	differentiate between an nscd failure, and a failure to execute
 | 
			
		||||
	due to no nscd with posix_spawn. Use our own run_command routine.
 | 
			
		||||
	* src/userdel.c: Use run_command()
 | 
			
		||||
 | 
			
		||||
2011-08-15  Nicolas François  <nicolas.francois@centraliens.net>
 | 
			
		||||
 | 
			
		||||
	* src/groupmod.c: Ignore return value from snprintf.
 | 
			
		||||
 
 | 
			
		||||
@@ -48,6 +48,8 @@ libshadow_la_SOURCES = \
 | 
			
		||||
	shadowio.c \
 | 
			
		||||
	shadowio.h \
 | 
			
		||||
	shadowmem.c \
 | 
			
		||||
	spawn.c \
 | 
			
		||||
	spawn.h \
 | 
			
		||||
	utent.c
 | 
			
		||||
 | 
			
		||||
if WITH_TCB
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										41
									
								
								lib/nscd.c
									
									
									
									
									
								
							
							
						
						
									
										41
									
								
								lib/nscd.c
									
									
									
									
									
								
							@@ -16,7 +16,9 @@
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <sys/wait.h>
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include "exitcodes.h"
 | 
			
		||||
#include "defines.h"
 | 
			
		||||
#include "spawn.h"
 | 
			
		||||
#include "nscd.h"
 | 
			
		||||
 | 
			
		||||
#define MSG_NSCD_FLUSH_CACHE_FAILED "Failed to flush the nscd cache.\n"
 | 
			
		||||
@@ -26,37 +28,32 @@
 | 
			
		||||
 */
 | 
			
		||||
int nscd_flush_cache (const char *service)
 | 
			
		||||
{
 | 
			
		||||
	pid_t pid, termpid;
 | 
			
		||||
	int err, status;
 | 
			
		||||
	char *spawnedArgs[] = {"/usr/sbin/nscd", "nscd", "-i", service, NULL};
 | 
			
		||||
	char *spawnedEnv[] = {NULL};
 | 
			
		||||
	pid_t pid;
 | 
			
		||||
	int err, status, code;
 | 
			
		||||
	const char *spawnedArgs[] = {"/usr/sbin/nscd", "nscd", "-i", service, NULL};
 | 
			
		||||
	const char *spawnedEnv[] = {NULL};
 | 
			
		||||
 | 
			
		||||
	/* spawn process */
 | 
			
		||||
	err = posix_spawn (&pid, spawnedArgs[0], NULL, NULL,
 | 
			
		||||
	                   spawnedArgs, spawnedEnv);
 | 
			
		||||
	if(0 != err)
 | 
			
		||||
	err = run_command (spawnedArgs[0], spawnedArgs, spawnedEnv, &status);
 | 
			
		||||
	if (0 != err)
 | 
			
		||||
	{
 | 
			
		||||
		/* run_command writes its own more detailed message. */
 | 
			
		||||
		(void) fputs (_(MSG_NSCD_FLUSH_CACHE_FAILED), stderr);
 | 
			
		||||
		(void) fprintf (stderr, "posix_spawn() error=%d\n", err);
 | 
			
		||||
		return -1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Wait for the spawned process to exit */
 | 
			
		||||
	termpid = TEMP_FAILURE_RETRY (waitpid (pid, &status, 0));
 | 
			
		||||
	if (-1 == termpid)
 | 
			
		||||
	code = WIFEXITED (status) ? WEXITSTATUS (status)
 | 
			
		||||
	                          : (WTERMSIG (status) + 128);
 | 
			
		||||
	if (code == E_CMD_NOTFOUND)
 | 
			
		||||
	{
 | 
			
		||||
		/* nscd is not installed, or it is installed but uses an
 | 
			
		||||
		   interpreter that is missing.  Probably the former. */
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
	if (code != 0)
 | 
			
		||||
	{
 | 
			
		||||
		(void) fprintf (stderr, "nscd exited with status %d", code);
 | 
			
		||||
		(void) fputs (_(MSG_NSCD_FLUSH_CACHE_FAILED), stderr);
 | 
			
		||||
		perror("waitpid");
 | 
			
		||||
		return -1;
 | 
			
		||||
	}
 | 
			
		||||
	else if (termpid != pid)
 | 
			
		||||
	{
 | 
			
		||||
		(void) fputs (_(MSG_NSCD_FLUSH_CACHE_FAILED), stderr);
 | 
			
		||||
		(void) fprintf (stderr, "waitpid returned %ld != %ld\n",
 | 
			
		||||
		               (long int) termpid, (long int) pid);
 | 
			
		||||
		return -1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
#else				/* USE_NSCD */
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										76
									
								
								lib/spawn.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								lib/spawn.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,76 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2011, Jonathan Nieder
 | 
			
		||||
 *
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without
 | 
			
		||||
 * modification, are permitted provided that the following conditions
 | 
			
		||||
 * are met:
 | 
			
		||||
 *
 | 
			
		||||
 * 1. Redistributions of source code must retain the above copyright
 | 
			
		||||
 *    notice, this list of conditions and the following disclaimer.
 | 
			
		||||
 * 2. Redistributions in binary form must reproduce the above copyright
 | 
			
		||||
 *    notice, this list of conditions and the following disclaimer in the
 | 
			
		||||
 *    documentation and/or other materials provided with the distribution.
 | 
			
		||||
 *
 | 
			
		||||
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | 
			
		||||
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | 
			
		||||
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 | 
			
		||||
 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FREEBSD
 | 
			
		||||
 * PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | 
			
		||||
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | 
			
		||||
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | 
			
		||||
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | 
			
		||||
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | 
			
		||||
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | 
			
		||||
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <config.h>
 | 
			
		||||
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <sys/wait.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include "exitcodes.h"
 | 
			
		||||
#include "spawn.h"
 | 
			
		||||
 | 
			
		||||
extern char **environ;
 | 
			
		||||
 | 
			
		||||
int run_command (const char *cmd, const char *argv[], const char *envp[],
 | 
			
		||||
                 int *status)
 | 
			
		||||
{
 | 
			
		||||
	pid_t pid, wpid;
 | 
			
		||||
 | 
			
		||||
	if (!envp)
 | 
			
		||||
		envp = (const char **)environ;
 | 
			
		||||
	pid = fork ();
 | 
			
		||||
	if (pid == 0) {
 | 
			
		||||
		execve (cmd, (char * const *) argv, (char * const *) envp);
 | 
			
		||||
		if (errno == ENOENT)
 | 
			
		||||
			exit (E_CMD_NOTFOUND);
 | 
			
		||||
		perror(cmd);
 | 
			
		||||
		exit (E_CMD_NOEXEC);
 | 
			
		||||
	} else if ((pid_t)-1 == pid) {
 | 
			
		||||
		int saved_errno = errno;
 | 
			
		||||
		perror ("fork");
 | 
			
		||||
		errno = saved_errno;
 | 
			
		||||
		return -1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	do {
 | 
			
		||||
		wpid = waitpid (pid, status, 0);
 | 
			
		||||
	} while ((pid_t)-1 == wpid && errno == EINTR);
 | 
			
		||||
 | 
			
		||||
	if ((pid_t)-1 == wpid) {
 | 
			
		||||
		int saved_errno = errno;
 | 
			
		||||
		perror ("waitpid");
 | 
			
		||||
		return -1;
 | 
			
		||||
	} else if (wpid != pid) {
 | 
			
		||||
		(void) fprintf (stderr, "waitpid returned %ld != %ld\n",
 | 
			
		||||
		                (long int) wpid, (long int) pid);
 | 
			
		||||
		errno = ECHILD;
 | 
			
		||||
		return -1;
 | 
			
		||||
	}
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										7
									
								
								lib/spawn.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								lib/spawn.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,7 @@
 | 
			
		||||
#ifndef _SPAWN_H
 | 
			
		||||
#define _SPAWN_H
 | 
			
		||||
 | 
			
		||||
extern int run_command (const char *cmd, const char *argv[],
 | 
			
		||||
                        const char *envp[], int *status);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@@ -59,6 +59,7 @@
 | 
			
		||||
#ifdef	SHADOWGRP
 | 
			
		||||
#include "sgroupio.h"
 | 
			
		||||
#endif				/* SHADOWGRP */
 | 
			
		||||
#include "spawn.h"
 | 
			
		||||
#ifdef WITH_TCB
 | 
			
		||||
#include <tcb.h>
 | 
			
		||||
#include "tcbfuncs.h"
 | 
			
		||||
@@ -628,6 +629,7 @@ static void update_user (void)
 | 
			
		||||
static void user_cancel (const char *user)
 | 
			
		||||
{
 | 
			
		||||
	const char *cmd;
 | 
			
		||||
	const char *argv[3];
 | 
			
		||||
	pid_t pid, wpid;
 | 
			
		||||
	int status;
 | 
			
		||||
 | 
			
		||||
@@ -635,18 +637,10 @@ static void user_cancel (const char *user)
 | 
			
		||||
	if (NULL == cmd) {
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	pid = fork ();
 | 
			
		||||
	if (pid == 0) {
 | 
			
		||||
		execl (cmd, cmd, user, (char *) 0);
 | 
			
		||||
		perror (cmd);
 | 
			
		||||
		exit (errno == ENOENT ? E_CMD_NOTFOUND : E_CMD_NOEXEC);
 | 
			
		||||
	} else if ((pid_t)-1 == pid) {
 | 
			
		||||
		perror ("fork");
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	do {
 | 
			
		||||
		wpid = wait (&status);
 | 
			
		||||
	} while ((wpid != pid) && ((pid_t)-1 != wpid));
 | 
			
		||||
	argv[0] = cmd;
 | 
			
		||||
	argv[1] = user;
 | 
			
		||||
	argv[2] = (char *)0;
 | 
			
		||||
	(void) run_command (cmd, argv, NULL, &status);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifdef EXTRA_CHECK_HOME_DIR
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user