Re: [PATCH 11/15] [src-policy] semodule: get module source

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, 2010-01-26 at 17:08 -0500, Caleb Case wrote:
> This adds the ability to retrieve the module source using semodule.
> 
>   -g,--get=MODULE_NAME [-o FILE] [-c] get module source
> 
> * More than one -g is allowed per command invocation.
> 
> * If output_name is “-“ then output is sent to standard out.
> 
> * If output is specified multiple times with oufile_name "-", then
>   append to stdout.
> 
> * If -o is not specified then the module is output to
>   <module name>.<language ext> in the current directory.
> 
> * If there is an existing file with the output file name (with or
>   without -o), then emit error and exit.
> 
> * -c will output the CIL instead of the source format.
> 
> Example:
> 
> # semodule -g alsa
> 
> This will retrieve the high level language source for the alsa module
> and save it to alsa.ref in the current directory.
> ---
>  policycoreutils/semodule/semodule.8 |    3 +
>  policycoreutils/semodule/semodule.c |  227 ++++++++++++++++++++++++++++++++++-
>  2 files changed, 228 insertions(+), 2 deletions(-)
> 
> diff --git a/policycoreutils/semodule/semodule.8 b/policycoreutils/semodule/semodule.8
> index 5fc10b3..bb6ae49 100644
> --- a/policycoreutils/semodule/semodule.8
> +++ b/policycoreutils/semodule/semodule.8
> @@ -55,6 +55,9 @@ enable module
>  .B  \-d,\-\-disable=MODULE_NAME
>  disable module
>  .TP
> +.B  \-g,\-\-get=MODULE_NAME [-o,--output=FILE] [-c,--cil]
> +Outputs module source to MODULE_NAME.ref. If output is set to '-' outputs on stdout, otherwise, outputs to the specified FILE. If cil is specified, then outputs the cil source instead of the original source.
> +.TP
>  .B  \-s,\-\-store	   
>  name of the store to operate on
>  .TP
> diff --git a/policycoreutils/semodule/semodule.c b/policycoreutils/semodule/semodule.c
> index c6b0d3c..0e3cc76 100644
> --- a/policycoreutils/semodule/semodule.c
> +++ b/policycoreutils/semodule/semodule.c
> @@ -20,6 +20,7 @@
>  #include <sys/mman.h>
>  #include <sys/stat.h>
>  #include <sys/types.h>
> +#include <limits.h>
>  
>  #include <semanage/modules.h>
>  
> @@ -27,17 +28,22 @@
>  
>  enum client_modes {
>  	NO_MODE, INSTALL_M, UPGRADE_M, BASE_M, REMOVE_M,
> -	LIST_M, RELOAD, PRIORITY_M, ENABLE_M, DISABLE_M
> +	LIST_M, RELOAD, PRIORITY_M, ENABLE_M, DISABLE_M,
> +	GET_M,
>  };
> +
>  /* list of modes in which one ought to commit afterwards */
>  static const int do_commit[] = {
>  	0, 1, 1, 1, 1,
>  	0, 0, 0, 1, 1,
> +	0,
>  };
>  
>  struct command {
>  	enum client_modes mode;
>  	char *arg;
> +	char *output;
> +	int cil;
>  };
>  static struct command *commands = NULL;
>  static int num_commands = 0;
> @@ -61,6 +67,7 @@ static void cleanup(void)
>  {
>  	while (--num_commands >= 0) {
>  		free(commands[num_commands].arg);
> +		free(commands[num_commands].output);
>  	}
>  	free(commands);
>  }
> @@ -117,6 +124,7 @@ static void usage(char *progname)
>  	printf("  -p,--priority=PRIORITY    set priority for following operations (1-999)\n");
>  	printf("  -e,--enable=MODULE_NAME   enable module\n");
>  	printf("  -d,--disable=MODULE_NAME  disable module\n");
> +	printf("  -g,--get=MODULE_NAME [-o FILE] [-c] get module source\n");
>  	printf("Other options:\n");
>  	printf("  -s,--store	   name of the store to operate on\n");
>  	printf("  -n,--noreload	   do not reload policy after commit\n");
> @@ -139,6 +147,8 @@ static void set_mode(enum client_modes new_mode, char *arg)
>  	commands = c;
>  	commands[num_commands].mode = new_mode;
>  	commands[num_commands].arg = NULL;
> +	commands[num_commands].output = NULL;
> +	commands[num_commands].cil = 0;
>  	num_commands++;
>  	if (arg != NULL) {
>  		if ((s = strdup(arg)) == NULL) {
> @@ -169,6 +179,9 @@ static void parse_command_line(int argc, char **argv)
>  		{"priority", required_argument, NULL, 'p'},
>  		{"enable", required_argument, NULL, 'e'},
>  		{"disable", required_argument, NULL, 'd'},
> +		{"get", required_argument, NULL, 'g'},
> +		{"output", required_argument, NULL, 'o'},
> +		{"cil", 0, NULL, 'c'},
>  		{NULL, 0, NULL, 0}
>  	};
>  	int i;
> @@ -178,7 +191,7 @@ static void parse_command_line(int argc, char **argv)
>  	create_store = 0;
>  	priority = 400;
>  	while ((i =
> -		getopt_long(argc, argv, "s:b:hi:l::vqr:u:RnBDp:e:d:", opts,
> +		getopt_long(argc, argv, "s:b:hi:l::vqr:u:RnBDp:e:d:g:o:c", opts,
>  			    NULL)) != -1) {
>  		switch (i) {
>  		case 'b':
> @@ -227,6 +240,53 @@ static void parse_command_line(int argc, char **argv)
>  		case 'd':
>  			set_mode(DISABLE_M, optarg);
>  			break;
> +		case 'g':
> +			set_mode(GET_M, optarg);
> +			break;
> +		case 'o':{
> +			/* no mode specified?? */
> +			if (num_commands == 0) {
> +				usage(argv[0]);
> +				exit(1);
> +			}
> +
> +			struct command *last = &commands[num_commands - 1];
> +
> +			/* only GET_M mode valid with -o */
> +			if (last->mode != GET_M) {
> +				usage(argv[0]);
> +				exit(1);
> +			}
> +
> +			last->output = strdup(optarg);
> +			if (last->output == NULL) {
> +				fprintf(stderr,
> +					"%s: Out of memory!\n",
> +					argv[0]);
> +				exit(1);
> +			}
> +
> +			break;
> +			}
> +		case 'c':{
> +			/* no mode specified?? */
> +			if (num_commands == 0) {
> +				usage(argv[0]);
> +				exit(1);
> +			}
> +
> +			struct command *last = &commands[num_commands - 1];
> +
> +			/* only GET_M mode valid with -c */
> +			if (last->mode != GET_M) {
> +				usage(argv[0]);
> +				exit(1);
> +			}
> +
> +			last->cil = 1;
> +
> +			break;
> +			}
>  		case '?':
>  		default:{
>  				usage(argv[0]);
> @@ -350,6 +410,8 @@ int main(int argc, char *argv[])
>  	for (i = 0; i < num_commands; i++) {
>  		enum client_modes mode = commands[i].mode;
>  		char *mode_arg = commands[i].arg;
> +		char *mode_output = commands[i].output;
> +		int mode_cil = commands[i].cil;
>  
>  		switch (mode) {
>  		case INSTALL_M:{
> @@ -582,6 +644,167 @@ cleanup_disable:
>  
>  				break;
>  			}
> +		case GET_M:{
> +				if (verbose) {
> +					printf("Attempting to get module '%s':\n", mode_arg);
> +				}
> +
> +				semanage_module_key_t *modkey = NULL;
> +				semanage_module_info_t *modinfo = NULL;
> +				const char *lang_ext = NULL;
> +				char *data = NULL;
> +				size_t data_len = 0;
> +
> +				int fd = -1;
> +				FILE *out = NULL;
> +				size_t nwrite = 0;
> +
> +				result = semanage_module_key_create(sh,
> +								    &modkey);
> +				if (result != 0) goto cleanup_get;
> +
> +				result = semanage_module_key_set_priority(
> +						sh,
> +						modkey,
> +						priority);
> +				if (result != 0) goto cleanup_get;
> +
> +				result = semanage_module_key_set_name(
> +						sh,
> +						modkey,
> +						mode_arg);
> +				if (result != 0) goto cleanup_get;
> +
> +				if (mode_cil == 0) {
> +					result = semanage_module_get(
> +							sh,
> +							modkey,
> +							&data,
> +							&data_len);
> +				}
> +				else {
> +					result = semanage_module_get_cil(
> +							sh,
> +							modkey,
> +							&data,
> +							&data_len);
> +				}
> +				if (result != 0) goto cleanup_get;
> +
> +				/* get language extension */
> +				result = semanage_module_get_module_info(
> +						sh,
> +						modkey,
> +						&modinfo);
> +				if (result != 0) goto cleanup_get;
> +
> +				if (mode_cil == 0) {
> +					result = semanage_module_info_get_lang_ext(
> +							sh,
> +							modinfo,
> +							&lang_ext);
> +					if (result != 0) goto cleanup_get;
> +				}
> +				else {
> +					/* current cil is refpol */
> +					lang_ext = "ref";
> +				}
> +
> +				if (mode_output == NULL ||
> +				    strcmp(mode_output, "-") != 0) {
> +					char path[PATH_MAX];
> +
> +					if (mode_output == NULL) {
> +						/* by default write out to <name>.<lang> */
> +						/* compose path */
> +
> +						result = snprintf(path,
> +								  sizeof(path) - 1,
> +								  "%s.%s",
> +								  mode_arg,
> +								  lang_ext);
> +						if (result < 0 ||
> +						    result >= (int)sizeof(path)) {
> +							fprintf(stderr,
> +								"%s: Unable to compose path for output file.\n",
> +								argv[0]);
> +							result = -1;
> +							goto cleanup_get;
> +						}
> +						result = 0;
> +					}
> +					else {
> +						if (strlen(mode_output) > sizeof(path) - 1) {
> +							fprintf(stderr,
> +								"%s: Path too long (%d > %d): '%s'\n",
> +								argv[0],
> +								strlen(mode_output),
> +								sizeof(path) - 1,
> +								mode_output);

I get the following warnings at the fprintf line:

cc -Werror -Wall -W -I/usr/include   -c -o semodule.o semodule.c
cc1: warnings being treated as errors
semodule.c: In function ‘main’:
semodule.c:772: error: format ‘%d’ expects type ‘int’, but argument 4
has type ‘size_t’
semodule.c:772: error: format ‘%d’ expects type ‘int’, but argument 5
has type ‘long unsigned int’
make[2]: *** [semodule.o] Error 1

> +							result = -1;
> +							goto cleanup_get;
> +						}
> +						strcpy(path, mode_output);
> +					}
> +
> +					/* open file iff it doesn't exist */
> +					fd = open(path,
> +						  O_WRONLY | O_CREAT | O_EXCL,
> +						  S_IRUSR | S_IWUSR);
> +					if (fd < 0) {
> +						fprintf(stderr,
> +							"%s: Unable to open output '%s'. (%s)\n",
> +							argv[0],
> +							path,
> +							strerror(errno));
> +						result = -1;
> +						goto cleanup_get;
> +					}
> +
> +					out = fdopen(fd, "w");
> +					if (out == NULL) {
> +						fprintf(stderr,
> +							"%s: Unable to open output '%s'. (%s)\n",
> +							argv[0],
> +							path,
> +							strerror(errno));
> +						result = -1;
> +						goto cleanup_get;
> +					}
> +				}
> +				else {
> +					/* otherwise we must be special '-' */
> +					out = stdout;
> +				}
> +
> +				nwrite = fwrite(data,
> +						data_len,
> +						1,
> +						out);
> +				if (nwrite != 1) {
> +					fprintf(stderr,
> +						"%s: Failed to write module to output.\n",
> +						argv[0]);
> +					result = -1;
> +					goto cleanup_get;
> +				}
> +
> +cleanup_get:
> +				if (out != NULL && out != stdout) {
> +					fclose(out);
> +					fd = -1;
> +				}
> +				if (fd >= 0) close(fd);
> +				free(data);
> +
> +				semanage_module_info_destroy(sh, modinfo);
> +				free(modinfo);
> +
> +				semanage_module_key_destroy(sh, modkey);
> +				free(modkey);
> +
> +				break;
> +			}
>  		default:{
>  				fprintf(stderr,
>  					"%s:  Unknown mode specified.\n",

-- 
James Carter <jwcart2@xxxxxxxxxxxxx>
National Security Agency


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@xxxxxxxxxxxxx with
the words "unsubscribe selinux" without quotes as the message.

[Index of Archives]     [Selinux Refpolicy]     [Linux SGX]     [Fedora Users]     [Fedora Desktop]     [Yosemite Photos]     [Yosemite Camping]     [Yosemite Campsites]     [KDE Users]     [Gnome Users]

  Powered by Linux