summaryrefslogtreecommitdiff
path: root/modules/pam_namespace/argv_parse.c
diff options
context:
space:
mode:
authorTomas Mraz <tm@t8m.info>2008-02-13 12:49:43 +0000
committerTomas Mraz <tm@t8m.info>2008-02-13 12:49:43 +0000
commit5607d7250357a548f04fe5e31cc960a2e54cf908 (patch)
treeb6f4d7a8ebee5d75db63b9f676c5eec2c86ba170 /modules/pam_namespace/argv_parse.c
parent6962e7e541546253d6d8d4d8e4bc5ca5290b8e5a (diff)
Relevant BUGIDs:
Purpose of commit: bugfix, new feature Commit summary: --------------- 2008-02-13 Tomas Mraz <t8m@centrum.cz> * modules/pam_namespace/Makefile.am: Add argv_parse files and namespace.d dir. * modules/pam_namespace/argv_parse.c: New file. * modules/pam_namespace/argv_parse.h: New file. * modules/pam_namespace/namespace.conf.5.xml: Document new features. * modules/pam_namespace/pam_namespace.8.xml: Likewise. * modules/pam_namespace/pam_namespace.h: Use SECURECONF_DIR define. Define NAMESPACE_D_DIR and NAMESPACE_D_GLOB. Define new option flags and polydir flags. (polydir_s): Add rdir, replace exclusive with flags, add init_script, owner, group, and mode. (instance_data): Add ruser, gid, and ruid. * modules/pam_namespace/pam_namespace.c: Remove now unused copy_ent(). (add_polydir_entry): Add the entry directly, no copy. (del_polydir): New function. (del_polydir_list): Call del_polydir(). (expand_variables, parse_create_params, parse_iscript_params, parse_method): New functions. (process_line): Call expand_variables() on polydir and instance prefix. Call argv_parse() instead of strtok_r(). Allocate struct polydir_s on heap. (parse_config_file): Parse .conf files from namespace.d dir after namespace.conf. (form_context): Call getcon() or get_default_context_with_level() when appropriate flags are set. (poly_name): Handle shared polydir flag. (inst_init): Execute non-default init script when specified. (create_polydir): New function. (create_dirs): Remove the code which checks the polydir. Do not call inst_init() when noinit flag is set. (ns_setup): Check the polydir and eventually create it if the create flag is set. (setup_namespace): Use ruser uid from idata. Set the namespace polydir pam data only when namespace was set up correctly. Unmount polydir based on ruser. (get_user_data): New function. (pam_sm_open_session): Check for use_current_context and use_default_context options. Call get_user_data(). (pam_sm_close_session): Call get_user_data().
Diffstat (limited to 'modules/pam_namespace/argv_parse.c')
-rw-r--r--modules/pam_namespace/argv_parse.c165
1 files changed, 165 insertions, 0 deletions
diff --git a/modules/pam_namespace/argv_parse.c b/modules/pam_namespace/argv_parse.c
new file mode 100644
index 00000000..acc76d74
--- /dev/null
+++ b/modules/pam_namespace/argv_parse.c
@@ -0,0 +1,165 @@
+/*
+ * argv_parse.c --- utility function for parsing a string into a
+ * argc, argv array.
+ *
+ * This file defines a function argv_parse() which parsing a
+ * passed-in string, handling double quotes and backslashes, and
+ * creates an allocated argv vector which can be freed using the
+ * argv_free() function.
+ *
+ * See argv_parse.h for the formal definition of the functions.
+ *
+ * Copyright 1999 by Theodore Ts'o.
+ *
+ * Permission to use, copy, modify, and distribute this software for
+ * any purpose with or without fee is hereby granted, provided that
+ * the above copyright notice and this permission notice appear in all
+ * copies. THE SOFTWARE IS PROVIDED "AS IS" AND THEODORE TS'O (THE
+ * AUTHOR) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. (Isn't
+ * it sick that the U.S. culture of lawsuit-happy lawyers requires
+ * this kind of disclaimer?)
+ *
+ * Version 1.1, modified 2/27/1999
+ */
+
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+#include "argv_parse.h"
+
+#define STATE_WHITESPACE 1
+#define STATE_TOKEN 2
+#define STATE_QUOTED 3
+
+/*
+ * Returns 0 on success, -1 on failure.
+ */
+int argv_parse(const char *in_buf, int *ret_argc, char ***ret_argv)
+{
+ int argc = 0, max_argc = 0;
+ char **argv, **new_argv, *buf, ch;
+ const char *cp = 0;
+ char *outcp = 0;
+ int state = STATE_WHITESPACE;
+
+ buf = malloc(strlen(in_buf)+1);
+ if (!buf)
+ return -1;
+
+ max_argc = 0; argc = 0; argv = 0;
+ outcp = buf;
+ for (cp = in_buf; (ch = *cp); cp++) {
+ if (state == STATE_WHITESPACE) {
+ if (isspace((int) ch))
+ continue;
+ /* Not whitespace, so start a new token */
+ state = STATE_TOKEN;
+ if (argc >= max_argc) {
+ max_argc += 3;
+ new_argv = realloc(argv,
+ (max_argc+1)*sizeof(char *));
+ if (!new_argv) {
+ if (argv) free(argv);
+ free(buf);
+ return -1;
+ }
+ argv = new_argv;
+ }
+ argv[argc++] = outcp;
+ }
+ if (state == STATE_QUOTED) {
+ if (ch == '"')
+ state = STATE_TOKEN;
+ else
+ *outcp++ = ch;
+ continue;
+ }
+ /* Must be processing characters in a word */
+ if (isspace((int) ch)) {
+ /*
+ * Terminate the current word and start
+ * looking for the beginning of the next word.
+ */
+ *outcp++ = 0;
+ state = STATE_WHITESPACE;
+ continue;
+ }
+ if (ch == '"') {
+ state = STATE_QUOTED;
+ continue;
+ }
+ if (ch == '\\') {
+ ch = *++cp;
+ switch (ch) {
+ case '\0':
+ ch = '\\'; cp--; break;
+ case 'n':
+ ch = '\n'; break;
+ case 't':
+ ch = '\t'; break;
+ case 'b':
+ ch = '\b'; break;
+ }
+ }
+ *outcp++ = ch;
+ }
+ if (state != STATE_WHITESPACE)
+ *outcp++ = '\0';
+ if (argv == 0) {
+ argv = malloc(sizeof(char *));
+ free(buf);
+ }
+ argv[argc] = 0;
+ if (ret_argc)
+ *ret_argc = argc;
+ if (ret_argv)
+ *ret_argv = argv;
+ return 0;
+}
+
+void argv_free(char **argv)
+{
+ if (*argv)
+ free(*argv);
+ free(argv);
+}
+
+#ifdef DEBUG_ARGV_PARSE
+/*
+ * For debugging
+ */
+
+#include <stdio.h>
+
+int main(int argc, char **argv)
+{
+ int ac, ret;
+ char **av, **cpp;
+ char buf[256];
+
+ while (!feof(stdin)) {
+ if (fgets(buf, sizeof(buf), stdin) == NULL)
+ break;
+ ret = argv_parse(buf, &ac, &av);
+ if (ret != 0) {
+ printf("Argv_parse returned %d!\n", ret);
+ continue;
+ }
+ printf("Argv_parse returned %d arguments...\n", ac);
+ for (cpp = av; *cpp; cpp++) {
+ if (cpp != av)
+ printf(", ");
+ printf("'%s'", *cpp);
+ }
+ printf("\n");
+ argv_free(av);
+ }
+ exit(0);
+}
+#endif