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); }
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; }
/* * 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 }
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; }
/** 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; }
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; }