Пример #1
0
void
cmd_execute(char *cmd)
{
   const char *errmsg = NULL;
   bool   found;
   char **argv;
   int    argc;
   int    found_idx = 0;
   int    num_matches;
   int    i;

   if (str2argv(cmd, &argc, &argv, &errmsg) != 0) {
      paint_error("parse error: %s in '%s'", errmsg, cmd);
      return;
   }

   found = false;
   num_matches = 0;
   for (i = 0; i < CommandPathSize; i++) {
      if (match_command_name(argv[0], CommandPath[i].name)) {
         found = true;
         found_idx = i;
         num_matches++;
      }
   }

   if (found && num_matches == 1)
      (CommandPath[found_idx].func)(argc, argv);
   else if (num_matches > 1)
      paint_error("Ambiguous abbreviation '%s'", argv[0]);
   else
      paint_error("Unknown commands '%s'", argv[0]);

   argv_free(&argc, &argv);
}
Пример #2
0
int
main (int argc, char **argv)
{
        char *evas          = NULL;
        struct invocable *i = NULL;
        char *b             = NULL;
        char *sargv         = NULL;

        evas = getenv (_GLUSTERD_CALLED_);
        if (evas && strcmp (evas, "1") == 0)
                /* OK, we know glusterd called us, no need to look for further config
                 * ... altough this conclusion should not inherit to our children
                 */
                unsetenv (_GLUSTERD_CALLED_);
        else {
                /* we regard all gsyncd invocations unsafe
                 * that do not come from glusterd and
                 * therefore restrict it
                 */
                restricted = 1;

                if (!getenv (_GSYNCD_DISPATCHED_)) {
                        evas = getenv ("SSH_ORIGINAL_COMMAND");
                        if (evas)
                                sargv = evas;
                        else {
                                evas = getenv ("SHELL");
                                if (evas && strcmp (basename (evas), "gsyncd") == 0 &&
                                    argc == 3 && strcmp (argv[1], "-c") == 0)
                                        sargv = argv[2];
                        }
                }

        }

        if (!(sargv && restricted))
                return invoke_gsyncd (argc, argv);

        argc = str2argv (sargv, &argv);
        if (argc == -1 || setenv (_GSYNCD_DISPATCHED_, "1", 1) == -1) {
                fprintf (stderr, "internal error\n");
                return 1;
        }

        b = basename (argv[0]);
        for (i = invocables; i->name; i++) {
                if (strcmp (b, i->name) == 0)
                        return i->invoker (argc, argv);
        }

        fprintf (stderr, "invoking %s in restricted SSH session is not allowed\n",
                 b);

        return 1;
}
Пример #3
0
/*
 *	Initialize the dictionary.
 */
static int my_dict_init(const char *dir, const char *fn,
			const char *src_file, int src_line)
{
	FILE	*fp;
	char 	dirtmp[256];
	char	buf[256];
	char	*p;
	int	line = 0;
	int	vendor;
	int	block_vendor;
	struct stat statbuf;
	char	*argv[MAX_ARGV];
	int	argc;
	DICT_ATTR *da, *block_tlv = NULL;

	if (strlen(fn) >= sizeof(dirtmp) / 2 ||
	    strlen(dir) >= sizeof(dirtmp) / 2) {
		fr_strerror_printf("dict_init: filename name too long");
		return -1;
	}

	/*
	 *	First see if fn is relative to dir. If so, create
	 *	new filename. If not, remember the absolute dir.
	 */
	if ((p = strrchr(fn, FR_DIR_SEP)) != NULL) {
		strcpy(dirtmp, fn);
		dirtmp[p - fn] = 0;
		dir = dirtmp;
	} else if (dir && dir[0] && strcmp(dir, ".") != 0) {
		snprintf(dirtmp, sizeof(dirtmp), "%s/%s", dir, fn);
		fn = dirtmp;
	}

	if ((fp = fopen(fn, "r")) == NULL) {
		if (!src_file) {
			fr_strerror_printf("dict_init: Couldn't open dictionary \"%s\": %s",
				   fn, strerror(errno));
		} else {
			fr_strerror_printf("dict_init: %s[%d]: Couldn't open dictionary \"%s\": %s",
				   src_file, src_line, fn, strerror(errno));
		}
		return -1;
	}

	stat(fn, &statbuf); /* fopen() guarantees this will succeed */
	if (!S_ISREG(statbuf.st_mode)) {
		fclose(fp);
		fr_strerror_printf("dict_init: Dictionary \"%s\" is not a regular file",
			   fn);
		return -1;
	}

	/*
	 *	Globally writable dictionaries means that users can control
	 *	the server configuration with little difficulty.
	 */
#ifdef S_IWOTH
	if ((statbuf.st_mode & S_IWOTH) != 0) {
		fclose(fp);
		fr_strerror_printf("dict_init: Dictionary \"%s\" is globally writable.  Refusing to start due to insecure configuration.",
			   fn);
		return -1;
	}
#endif

	dict_stat_add(fn, &statbuf);

	/*
	 *	Seed the random pool with data.
	 */
	fr_rand_seed(&statbuf, sizeof(statbuf));

	block_vendor = 0;

	while (fgets(buf, sizeof(buf), fp) != NULL) {
		line++;
		if (buf[0] == '#' || buf[0] == 0 ||
		    buf[0] == '\n' || buf[0] == '\r')
			continue;

		/*
		 *  Comment characters should NOT be appearing anywhere but
		 *  as start of a comment;
		 */
		p = strchr(buf, '#');
		if (p) *p = '\0';

		argc = str2argv(buf, argv, MAX_ARGV);
		if (argc == 0) continue;

		if (argc == 1) {
			fr_strerror_printf( "dict_init: %s[%d] invalid entry",
				    fn, line);
			fclose(fp);
			return -1;
		}

		/*
		 *	Process VALUE lines.
		 */
		if (strcasecmp(argv[0], "VALUE") == 0) {
			if (process_value(fn, line,
					  argv + 1, argc - 1) == -1) {
				fclose(fp);
				return -1;
			}
			continue;
		}

		/*
		 *	Perhaps this is an attribute.
		 */
		if (strcasecmp(argv[0], "ATTRIBUTE") == 0) {
			if (process_attribute(fn, line, block_vendor,
					      block_tlv,
					      argv + 1, argc - 1) == -1) {
				fclose(fp);
				return -1;
			}
			continue;
		}

		/*
		 *	See if we need to import another dictionary.
		 */
		if (strcasecmp(argv[0], "$INCLUDE") == 0) {
			if (my_dict_init(dir, argv[1], fn, line) < 0) {
				fclose(fp);
				return -1;
			}
			continue;
		} /* $INCLUDE */

		if (strcasecmp(argv[0], "VALUE-ALIAS") == 0) {
			if (process_value_alias(fn, line,
						argv + 1, argc - 1) == -1) {
				fclose(fp);
				return -1;
			}
			continue;
		}

		/*
		 *	Process VENDOR lines.
		 */
		if (strcasecmp(argv[0], "VENDOR") == 0) {
			if (process_vendor(fn, line,
					   argv + 1, argc - 1) == -1) {
				fclose(fp);
				return -1;
			}
			continue;
		}

		if (strcasecmp(argv[0], "BEGIN-TLV") == 0) {
			if (argc != 2) {
				fr_strerror_printf(
				"dict_init: %s[%d] invalid BEGIN-TLV entry",
					fn, line);
				fclose(fp);
				return -1;
			}

			da = dict_attrbyname(argv[1]);
			if (!da) {
				fr_strerror_printf(
					"dict_init: %s[%d]: unknown attribute %s",
					fn, line, argv[1]);
				fclose(fp);
				return -1;
			}

			if (da->type != PW_TYPE_TLV) {
				fr_strerror_printf(
					"dict_init: %s[%d]: attribute %s is not of type tlv",
					fn, line, argv[1]);
				fclose(fp);
				return -1;
			}

			if (block_tlv) {
				fr_strerror_printf(
					"dict_init: %s[%d]: Cannot nest TLVs",
					fn, line);
				fclose(fp);
				return -1;
			}

			block_tlv = da;
			continue;
		} /* BEGIN-TLV */

		if (strcasecmp(argv[0], "END-TLV") == 0) {
			if (argc != 2) {
				fr_strerror_printf(
				"dict_init: %s[%d] invalid END-TLV entry",
					fn, line);
				fclose(fp);
				return -1;
			}

			da = dict_attrbyname(argv[1]);
			if (!da) {
				fr_strerror_printf(
					"dict_init: %s[%d]: unknown attribute %s",
					fn, line, argv[1]);
				fclose(fp);
				return -1;
			}

			if (da != block_tlv) {
				fr_strerror_printf(
					"dict_init: %s[%d]: END-TLV %s does not match any previous BEGIN-TLV",
					fn, line, argv[1]);
				fclose(fp);
				return -1;
			}
			block_tlv = NULL;
			continue;
		} /* END-VENDOR */

		if (strcasecmp(argv[0], "BEGIN-VENDOR") == 0) {
			if (argc != 2) {
				fr_strerror_printf(
				"dict_init: %s[%d] invalid BEGIN-VENDOR entry",
					fn, line);
				fclose(fp);
				return -1;
			}

			vendor = dict_vendorbyname(argv[1]);
			if (!vendor) {
				fr_strerror_printf(
					"dict_init: %s[%d]: unknown vendor %s",
					fn, line, argv[1]);
				fclose(fp);
				return -1;
			}
			block_vendor = vendor;
			continue;
		} /* BEGIN-VENDOR */

		if (strcasecmp(argv[0], "END-VENDOR") == 0) {
			if (argc != 2) {
				fr_strerror_printf(
				"dict_init: %s[%d] invalid END-VENDOR entry",
					fn, line);
				fclose(fp);
				return -1;
			}

			vendor = dict_vendorbyname(argv[1]);
			if (!vendor) {
				fr_strerror_printf(
					"dict_init: %s[%d]: unknown vendor %s",
					fn, line, argv[1]);
				fclose(fp);
				return -1;
			}

			if (vendor != block_vendor) {
				fr_strerror_printf(
					"dict_init: %s[%d]: END-VENDOR %s does not match any previous BEGIN-VENDOR",
					fn, line, argv[1]);
				fclose(fp);
				return -1;
			}
			block_vendor = 0;
			continue;
		} /* END-VENDOR */

		/*
		 *	Any other string: We don't recognize it.
		 */
		fr_strerror_printf("dict_init: %s[%d] invalid keyword \"%s\"",
			   fn, line, argv[0]);
		fclose(fp);
		return -1;
	}
	fclose(fp);
	return 0;
}
/*
 * filterBinary:
 *
 * This routine will call routines to parse entries from an ASCII format
 * to a binary format recognized by the Ascend boxes.
 *
 *	pair:			Pointer to value_pair to place return.
 *
 *	valstr:			The string to parse
 *
 *	return:			-1 for error or 0.
 */
int ascend_parse_filter(VALUE_PAIR *vp, char const *value, size_t len)
{
	int		token, type;
	int		rcode;
	int		argc;
	char		*argv[32];
	ascend_filter_t filter;
	char		*p;

	rcode = -1;

	/*
	 *	Rather than printing specific error messages, we create
	 *	a general one here, which won't be used if the function
	 *	returns OK.
	 */
	fr_strerror_printf("Text is not in proper format");

	/*
	 *	Tokenize the input string in the VP.
	 *
	 *	Once the filter is *completelty* parsed, then we will
	 *	over-write it with the final binary filter.
	 */
	p = talloc_memdup(vp, value, len);
	p[len] = '\0';
	argc = str2argv(p, argv, 32);
	if (argc < 3) {
		talloc_free(p);
		return -1;
	}

	/*
	 *	Decide which filter type it is: ip, ipx, or generic
	 */
	type = fr_str2int(filterType, argv[0], -1);
	memset(&filter, 0, sizeof(filter));

	/*
	 *	Validate the filter type.
	 */
	switch (type) {
	case RAD_FILTER_GENERIC:
	case RAD_FILTER_IP:
	case RAD_FILTER_IPX:
		filter.type = type;
		break;

	default:
		fr_strerror_printf("Unknown Ascend filter type \"%s\"", argv[0]);
		talloc_free(p);
		return -1;
		break;
	}

	/*
	 *	Parse direction
	 */
	token = fr_str2int(filterKeywords, argv[1], -1);
	switch (token) {
	case FILTER_IN:
		filter.direction = 1;
		break;

	case FILTER_OUT:
		filter.direction = 0;
		break;

	default:
		fr_strerror_printf("Unknown Ascend filter direction \"%s\"", argv[1]);
		talloc_free(p);
		return -1;
	}

	/*
	 *	Parse action
	 */
	token = fr_str2int(filterKeywords, argv[2], -1);
	switch (token) {
	case FILTER_FORWARD:
		filter.forward = 1;
		break;

	case FILTER_DROP:
		filter.forward = 0;
		break;

	default:
		fr_strerror_printf("Unknown Ascend filter action \"%s\"", argv[2]);
		talloc_free(p);
		return -1;
		break;
	}


	switch (type) {
	case RAD_FILTER_GENERIC:
		rcode = ascend_parse_generic(argc - 3, &argv[3], &filter.u.generic);
		break;

	case RAD_FILTER_IP:
		rcode = ascend_parse_ip(argc - 3, &argv[3], &filter.u.ip);
		break;

	case RAD_FILTER_IPX:
		rcode = ascend_parse_ipx(argc - 3, &argv[3], &filter.u.ipx);
		break;
	}

	/*
	 *	Touch the VP only if everything was OK.
	 */
	if (rcode == 0) {
		vp->length = sizeof(filter);
		memcpy(vp->vp_filter, &filter, sizeof(filter));
	}

	talloc_free(p);
	return rcode;

#if 0
    /*
     * if 'more' is set then this new entry must exist, be a
     * FILTER_GENERIC_TYPE, direction and disposition must match for
     * the previous 'more' to be valid. If any should fail then TURN OFF
     * previous 'more'
     */
    if( prevRadvp ) {
	filt = ( RadFilter * )prevRadvp->vp_strvalue;
	if(( tok != FILTER_GENERIC_TYPE ) || (rc == -1 ) ||
	   ( prevRadvp->attribute != vp->attribute ) ||
	   ( filt->indirection != radFil.indirection ) ||
	   ( filt->forward != radFil.forward ) ) {
	    gen = &filt->u.generic;
	    gen->more = false;
	    fr_strerror_printf("filterBinary:  'more' for previous entry doesn't match: %s.\n",
		     valstr);
	}
    }
    prevRadvp = NULL;
    if( rc != -1 && tok == FILTER_GENERIC_TYPE ) {
	if( radFil.u.generic.more ) {
	    prevRadvp = vp;
	}
    }

    if( rc != -1 ) {
	    vpmemcpy(vp, &radFil, vp->length );
    }
    return(rc);

#endif
}
Пример #5
0
int
main (int argc, char **argv)
{
        int               ret   = -1;
        char             *evas  = NULL;
        struct invocable *i     = NULL;
        char             *b     = NULL;
        char             *sargv = NULL;

#ifdef USE_LIBGLUSTERFS
        glusterfs_ctx_t *ctx = NULL;

        ctx = glusterfs_ctx_new ();
        if (!ctx)
                return ENOMEM;

        if (glusterfs_globals_init (ctx))
                return 1;

        THIS->ctx = ctx;
        ret = default_mem_acct_init (THIS);
        if (ret) {
                fprintf (stderr, "internal error: mem accounting failed\n");
                return 1;
        }
#endif

        evas = getenv (_GLUSTERD_CALLED_);
        if (evas && strcmp (evas, "1") == 0)
                /* OK, we know glusterd called us, no need to look for further config
                 *...although this conclusion should not inherit to our children
                 */
                unsetenv (_GLUSTERD_CALLED_);
        else {
                /* we regard all gsyncd invocations unsafe
                 * that do not come from glusterd and
                 * therefore restrict it
                 */
                restricted = 1;

                if (!getenv (_GSYNCD_DISPATCHED_)) {
                        evas = getenv ("SSH_ORIGINAL_COMMAND");
                        if (evas)
                                sargv = evas;
                        else {
                                evas = getenv ("SHELL");
                                if (evas && strcmp (basename (evas), "gsyncd") == 0 &&
                                    argc == 3 && strcmp (argv[1], "-c") == 0)
                                        sargv = argv[2];
                        }
                }

        }

        if (!(sargv && restricted))
                return invoke_gsyncd (argc, argv);

        argc = str2argv (sargv, &argv);
        if (argc == -1 || setenv (_GSYNCD_DISPATCHED_, "1", 1) == -1) {
                fprintf (stderr, "internal error\n");
                return 1;
        }

        b = basename (argv[0]);
        for (i = invocables; i->name; i++) {
                if (strcmp (b, i->name) == 0)
                        return i->invoker (argc, argv);
        }

        fprintf (stderr, "invoking %s in restricted SSH session is not allowed\n",
                 b);

        free(argv);
        return 1;
}
Пример #6
0
/** Filter binary
 *
 * This routine will call routines to parse entries from an ASCII format
 * to a binary format recognized by the Ascend boxes.
 *
 * @param out Where to write parsed filter.
 * @param value ascend filter text.
 * @param len of value.
 * @return -1 for error or 0.
 */
int ascend_parse_filter(value_data_t *out, char const *value, size_t len)
{
    int		token, type;
    int		rcode;
    int		argc;
    char		*argv[32];
    ascend_filter_t filter;
    char		*p;

    rcode = -1;

    /*
     *	Tokenize the input string in the VP.
     *
     *	Once the filter is *completely* parsed, then we will
     *	over-write it with the final binary filter.
     */
    p = talloc_memdup(NULL, value, len+1);
    p[len] = '\0';

    /*
     *	Rather than printing specific error messages, we create
     *	a general one here, which won't be used if the function
     *	returns OK.
     */
    fr_strerror_printf("Failed parsing \"%s\" as ascend filer", p);

    argc = str2argv(p, argv, 32);
    if (argc < 3) {
        talloc_free(p);
        return -1;
    }

    /*
     *	Decide which filter type it is: ip, ipx, or generic
     */
    type = fr_str2int(filterType, argv[0], -1);
    memset(&filter, 0, sizeof(filter));

    /*
     *	Validate the filter type.
     */
    switch (type) {
    case RAD_FILTER_GENERIC:
    case RAD_FILTER_IP:
    case RAD_FILTER_IPX:
        filter.type = type;
        break;

    default:
        fr_strerror_printf("Unknown Ascend filter type \"%s\"", argv[0]);
        talloc_free(p);
        return -1;
    }

    /*
     *	Parse direction
     */
    token = fr_str2int(filterKeywords, argv[1], -1);
    switch (token) {
    case FILTER_IN:
        filter.direction = 1;
        break;

    case FILTER_OUT:
        filter.direction = 0;
        break;

    default:
        fr_strerror_printf("Unknown Ascend filter direction \"%s\"", argv[1]);
        talloc_free(p);
        return -1;
    }

    /*
     *	Parse action
     */
    token = fr_str2int(filterKeywords, argv[2], -1);
    switch (token) {
    case FILTER_FORWARD:
        filter.forward = 1;
        break;

    case FILTER_DROP:
        filter.forward = 0;
        break;

    default:
        fr_strerror_printf("Unknown Ascend filter action \"%s\"", argv[2]);
        talloc_free(p);
        return -1;
    }


    switch (type) {
    case RAD_FILTER_GENERIC:
        rcode = ascend_parse_generic(argc - 3, &argv[3], &filter.u.generic);
        break;

    case RAD_FILTER_IP:
        rcode = ascend_parse_ip(argc - 3, &argv[3], &filter.u.ip);
        break;

    case RAD_FILTER_IPX:
        rcode = ascend_parse_ipx(argc - 3, &argv[3], &filter.u.ipx);
        break;
    }

    /*
     *	Touch the VP only if everything was OK.
     */
    if (rcode == 0) memcpy(out->filter, &filter, sizeof(filter));
    talloc_free(p);
    printf("%i", rcode);

    return rcode;
}
Пример #7
0
proc_list *parse_proc(char *cmd) {
    char *str = cmd,*p,*pt,*st,*ed,*ptrcmd;
    proc_list *ret,*ptr;
    ret = NULL;
    while(strchr(str,'|') != NULL) {
        if(ret == NULL) {
            ret = (proc_list *)malloc(sizeof(proc_list));
            ptr = ret;
        } else {
            ptr->next = (proc_list *)malloc(sizeof(proc_list));
            ptr = ptr->next;
        }
        p = strchr(str,'|');

        ptrcmd = (char *)malloc(sizeof(char)*(p-str+1));
        strncpy(ptrcmd,str,p-str);
        *(ptrcmd+(p-str)) = 0;
        trim(ptrcmd);
        if(strlen(ptrcmd) == 0) {
            ptr->redir_type =-1;
            ptr->next = NULL;
            free(ptrcmd);
            str = p+1;
            continue;
        }
        if(ptrcmd[strlen(ptrcmd)-1] == '&') {
            ptrcmd[strlen(ptrcmd)-1] = 0;
            ptr->run_background = 1;
        } else {
            ptr->run_background = 0;
        }
        if((pt=strstr(ptrcmd,">>") != NULL)) {
            ptr->redir_type = 3;
        } else if((pt=strchr(ptrcmd,'>')) != NULL) {
            ptr->redir_type = 2;
        } else if((pt=strchr(ptrcmd,'<')) != NULL) {
            ptr->redir_type = 1;
        } else {
            ptr->redir_type = 0;
        }
        if(ptr->redir_type != 0) {
            st = pt;
            while(*st == ' ' || *st == '\t' || *st == '>' || *st == '<')
                st++;
            ed=st;
            while(!(*ed == ' ' || *ed == '\t' || *ed == '>' || *ed == '<' || *ed == '|' || *ed == 0 || *ed == '\n'))
                ed++;
            if(st==ed) ptr->redir_type = -1;
            else {
                ptr->redir = (char *)malloc(sizeof(char)*(ed-st+1));
                strncpy(ptr->redir,st,ed-st);
                *(ptr->redir+(ed-st)) = 0;
                strcpy(pt,ed);
            }
        } else {
            ptr->redir = NULL;
        }
        if(ptr->redir_type != -1) ptr->argv = str2argv(ptrcmd);
        str = p+1;
        ptr->next = NULL;
        free(ptrcmd);
    }
    if(ret == NULL) {
        ret = (proc_list *)malloc(sizeof(proc_list));
        ptr = ret;
    } else {
        ptr->next = (proc_list *)malloc(sizeof(proc_list));
        ptr = ptr->next;
    }
    ptrcmd = (char *)malloc(sizeof(char)*(strlen(str)+1));
    strcpy(ptrcmd,str);
    trim(ptrcmd);
    if(strlen(ptrcmd) == 0) {
        ptr->redir_type = -1;
        ptr->next = NULL;
        free(ptrcmd);
        return ret;
    }
    if(ptrcmd[strlen(ptrcmd)-1] == '&') {
        ptrcmd[strlen(ptrcmd)-1] = 0;
        ptr->run_background = 1;
    } else {
        ptr->run_background = 0;
    }
    if((pt=strstr(ptrcmd,">>")) != NULL) {
        ptr->redir_type = 3;
    } else if((pt=strchr(ptrcmd,'>')) != NULL) {
        ptr->redir_type = 2;
    } else if((pt=strchr(ptrcmd,'<')) != NULL) {
        ptr->redir_type = 1;
    } else {
        ptr->redir_type = 0;
    }
    if(ptr->redir_type != 0) {
        st = pt;
        while(*st == ' ' || *st == '\t' || *st == '>' || *st == '<')
            st++;
        ed=st;
        while(!(*ed == ' ' || *ed == '\t' || *ed == '>' || *ed == '<' || *ed == '|' || *ed == 0 || *ed == '\n'))
            ed++;
        if(st == ed) ptr->redir_type = -1;
        else {
            ptr->redir = (char *)malloc(sizeof(char)*(ed-st+1));
            strncpy(ptr->redir,st,ed-st);
            *(ptr->redir+(ed-st)) = 0;
            strcpy(pt,ed);
        }
    } else {
        ptr->redir = NULL;
    }
    if(ptr->redir_type != -1) ptr->argv = str2argv(ptrcmd);
    ptr->next = NULL;
    free(ptrcmd);
    return ret;
}