From 60140d51cde34993da1d944cfdd5827f87360b00 Mon Sep 17 00:00:00 2001 From: danw Date: Fri, 3 Oct 1997 17:31:18 +0000 Subject: [PATCH] Move UNIX->SQL wildcard conversion from the validation stage to the query-building stage since we know we have to do it iff the argument was preceded by a `LIKE'. Also, redo build_qual and build_sql_statment such that they aren't vulnerable to buffer overruns. --- server/mr_server.h | 3 +- server/qrtn.pc | 292 ++++++++++++++++++++------------------------ server/qsupport.pc | 17 ++- server/queries2.c | 257 +++++++++++++------------------------- server/query.h | 5 +- server/qvalidate.pc | 71 +---------- 6 files changed, 232 insertions(+), 413 deletions(-) diff --git a/server/mr_server.h b/server/mr_server.h index ca999313..452ca77b 100644 --- a/server/mr_server.h +++ b/server/mr_server.h @@ -161,7 +161,7 @@ void sanity_check_queries(void); int set_krb_mapping(char *name, char *login, int ok, int *kid, int *uid); int find_member(char *list_type, int list_id, client *cl); int do_for_all_rows(char *query, int count, int (*action)(), int actarg); -int build_qual(char *fmt, int argc, char *argv[], char *qual); +char *build_qual(char *fmt, int argc, char *argv[]); /* prototyoes from qsupport.dc */ @@ -170,7 +170,6 @@ int set_pop_usage(int id, int cnt); /* prototypes from qvalidate.dc */ void sanity_check_database(void); int add_string(char *name); -int convert_wildcards(char *arg); /* prototypes from mr_main.c */ void clist_delete(client *cp); diff --git a/server/qrtn.pc b/server/qrtn.pc index d50754f0..7ded21c7 100644 --- a/server/qrtn.pc +++ b/server/qrtn.pc @@ -50,8 +50,8 @@ int do_append(struct query *q, char *argv[], char *pqual, int (*action)(), char *actarg); int do_delete(struct query *q, char *qual, int (*action)(), char *actarg); -void build_sql_stmt(char *result_buf, char *cmd, char *targetlist, - char *argv[], char *qual); +char *build_sql_stmt(char *cmd, char *targetlist, char *argv[], + int argc, char *qual, char *sort); /* from qvalidate.dc */ int validate_fields(struct query *q, char *argv[], struct valobj *vo, int n); @@ -149,8 +149,7 @@ int mr_process_query(cl, name, argc, argv_ro, action, actarg) register struct query *q; register int status; register struct validate *v; - char qual[256]; - char *pqual; + char *qual = NULL; EXEC SQL BEGIN DECLARE SECTION; char *table; EXEC SQL END DECLARE SECTION; @@ -200,21 +199,14 @@ int mr_process_query(cl, name, argc, argv_ro, action, actarg) if (status != MR_EXISTS) break; } - /* build "where" clause if needed */ - if (q->qual) { - build_qual(q->qual, q->argc, Argv, qual); - pqual = qual; - } else { - pqual = 0; - } - /* if there is a followup routine, then we must save the results */ /* of the first query for use by the followup routine */ /* if q->rvar = NULL, perform post_rtn only */ if (q->rvar) { + if (q->qual) qual = build_qual(q->qual, q->argc, Argv); if (v && v->post_rtn) { sq = sq_create(); - status = do_retrieve(q, pqual, sq_save_args, (char *)sq); + status = do_retrieve(q, qual, sq_save_args, (char *)sq); if (status != MR_SUCCESS) { sq_destroy(sq); break; @@ -222,7 +214,7 @@ int mr_process_query(cl, name, argc, argv_ro, action, actarg) status = (*v->post_rtn)(q, sq, v, action, actarg, cl); } else { /* normal retrieve */ - status = do_retrieve(q, pqual, action, actarg); + status = do_retrieve(q, qual, action, actarg); } if (status != MR_SUCCESS) break; } else { @@ -241,7 +233,7 @@ int mr_process_query(cl, name, argc, argv_ro, action, actarg) /* build "where" clause and perform update */ /* if q->rvar = NULL, perform post_rtn only */ if (q->rvar) { - build_qual(q->qual, q->argc, Argv, qual); + qual = build_qual(q->qual, q->argc, Argv); incremental_before(q->rtable, qual, argv_ro); status = do_update(q, &Argv[q->argc], qual, action, actarg); incremental_after(q->rtable, qual, argv_ro); @@ -267,26 +259,20 @@ int mr_process_query(cl, name, argc, argv_ro, action, actarg) if (status != MR_NO_MATCH) break; } - /* build "where" clause if needed */ - if (q->qual) { - build_qual(q->qual, q->argc, Argv, qual); - pqual = qual; - } else { - pqual = 0; - } - /* perform the append */ /* if q->rvar = NULL, perform post_rtn only */ if (q->rvar) { + if (q->qual) qual = build_qual(q->qual, q->argc, Argv); incremental_clear_before(); - status = do_append(q, &Argv[q->argc], pqual, action, actarg); + status = do_append(q, &Argv[q->argc], qual, action, actarg); if (status != MR_SUCCESS) break; if (v && v->object_id) { + qual = realloc(qual, 128); sprintf(qual, "%s.%s = %s",q->rvar, v->object_id, Argv[q->argc+q->vcnt]); incremental_after(q->rtable, qual, argv_ro); } else - incremental_after(q->rtable, pqual, argv_ro); + incremental_after(q->rtable, qual, argv_ro); table = table_name[q->rtable]; EXEC SQL UPDATE tblstats @@ -308,7 +294,7 @@ int mr_process_query(cl, name, argc, argv_ro, action, actarg) /* build "where" clause and perform delete */ /* if q->rvar = NULL, perform post_rtn only */ if (q->rvar) { - build_qual(q->qual, q->argc, Argv, qual); + qual = build_qual(q->qual, q->argc, Argv); table = table_name[q->rtable]; incremental_before(q->rtable, qual, argv_ro); status = do_delete(q, qual, action, actarg); @@ -364,48 +350,92 @@ out: } } cache_commit(); /* commit following abort is safe */ + if (qual) free(qual); if (status != MR_SUCCESS && log_flags & LOG_RES) com_err(whoami, status, " (Query failed)"); return(status); } -int build_qual(fmt_buf, argc, argv, qual) - char *fmt_buf, *argv[], *qual; +char *build_qual(fmt_buf, argc, argv) + char *fmt_buf, *argv[]; int argc; { - char *res, *fmt; - - for(res=qual, fmt=fmt_buf; *fmt; fmt++) { - if(*fmt=='%') { - if(*++fmt) { - switch(*fmt) { - case '%': /* %% -> % */ - *res++ = *fmt; - break; - case 's': - if(*argv[0]) { - char *p=*argv; - while(*p) { - if(*p=='\'') *res++='\''; /* double the ' */ - *res++=*p++; + char *res, *result_buf, *fmt, *arg, *like; + + result_buf = malloc(2*(strlen(fmt_buf) + argc*ARGLEN)); + + res = result_buf; + fmt = fmt_buf; + + /* Look through the format for LIKE expressions and arguments. + Substitute in the arguments, and simplify the `LIKE's to `='s + where possible. */ + + while (*fmt) { + like = strstr(fmt, "LIKE"); + arg = strchr(fmt, '%'); + + if (!like && !arg) { + /* only plain text remains */ + strcpy(res, fmt); + break; + } else if (!like || arg < like) { + /* copy to arg, then substitute */ + strncpy(res, fmt, arg - fmt - 1); + res += arg - fmt; + if(*++arg) { + switch(*arg++) { + case '%': + *res++ = '%'; + break; + case 's': + if(*argv[0]) { + char *p = *argv; + while(*p) { + if(*p == '\'') *res++ = '\''; + *res++ = *p++; + } } - } - argv++; - break; - case 'd': - res+=sprintf(res,"%d",*(int *)*argv++); - break; - default: /* Swallow other %? pairs */ - break; + argv++; + break; + case 'd': + res += sprintf(res, "%d", *(int *)*argv++); + break; } - } else break; - } else *res++ = *fmt; /* text -> result buffer */ + } + fmt = arg; + arg = strchr(fmt, '%'); + } else { + /* copy over up to the arg, then copy and convert the arg */ + char *p; + int escape = 0; + + strncpy(res, fmt, arg - fmt - 1); + res += arg - fmt; + for (p = *argv++; *p; p++) { + switch (*p) { + case '\'': *res++ = '\''; *res++ = '\''; break; + case '*': *res++ = '%'; break; + case '?': *res++ = '_'; break; + case '%': + case '_': *res++ = '*'; *res++ = *p; escape = 1; break; + default: *res++ = *p; + } + } + if (escape) res += sprintf(res, " ESCAPE '*'"); + + fmt += 2; + arg = strchr(fmt, '%'); + like = strstr(fmt, "LIKE"); + } } - *res='\0'; + + result_buf = realloc(result_buf, strlen(result_buf) + 1); + return result_buf; } -/* Build arguement vector, verify query and arguments */ +/* Build argument vector, verify query and arguments */ int privileged; @@ -553,122 +583,42 @@ int do_retrieve(q, pqual, action, actarg) char *pqual, *actarg; int (*action)(); { - build_sql_stmt(stmt_buf,"SELECT",q->tlist,NULL,pqual); - if(q->sort) { - strcat(stmt_buf," ORDER BY "); - strcat(stmt_buf,q->sort); - } + char *stmt; + int status; - return do_for_all_rows(stmt_buf, q->vcnt, action, (int)actarg); + stmt = build_sql_stmt("SELECT",q->tlist,NULL,0,pqual,q->sort); + status = do_for_all_rows(stmt_buf, q->vcnt, action, (int)actarg); + free(stmt); + return status; } -char *sqlstrstr(str, pat) - char *str, *pat; -{ - register char *p=pat; - - do { - if(*str=='\'') { /* Skip over single-quote delimited substrings */ - while(*++str && (*str!='\'')) - ; - continue; - } - if(*str==*p) { - register char *s; - s=str; - while(*++p && (*++s==*p)) - ; - if(*p) p=pat; /* failed */ - } - } while(*p && *++str); - - if(!*str) str=NULL; - return(str); -} - -void optimize_sql_stmt(buf) - char *buf; -{ - char *point=buf, *pat, *eopat, *esc1, *esc2, *csr; - - for(point=buf; point=sqlstrstr(point,"LIKE"); point++) { - /* Now pointing to string "LIKE" */ - - /* Look at next word */ - for(pat=point+4; *pat==' '; pat++) ; - - /* Is it a single-quote delimited string? */ - if(*pat!='\'') continue; - - /* look for "escape" clause - save escape character */ - /* 1. Find end of pattern */ - for(eopat=pat+1; 1; eopat++) { - if(*eopat=='\'') { - if(eopat[1]=='\'') /* single-quote is self-escaping */ - eopat++; - else - break; - } - } - - /* 2. Look at next word */ - for(esc1=eopat; *++esc1==' ';) ; - - /* 3. esc1=0 if not "ESCAPE '?'", where the ? may be any character. */ - if(strncmp(esc1,"ESCAPE",6)) esc1=NULL; - - if(esc1) { - for(esc2=esc1+6; *esc2==' '; esc2++) ; - - if(*esc2++!='\'') continue; /* Bad SQL syntax. Skip. */ - /* esc2 now points at the escape character itself */ - if(esc2[1]!='\'') continue; /* Weird escape string. Skip. */ - } else { - esc2="\\"; - } - - /* Is pattern free from special characters? */ - for(csr=pat; csr % */ + case '%': *res++ = *fmt; break; case 's': if(*argv[0]) { char *p=*argv; while(*p) { - if(*p=='\'') *res++='\''; /* double the ' */ + if(*p=='\'') *res++='\''; *res++=*p++; } } @@ -677,15 +627,23 @@ void build_sql_stmt(result_buf, cmd, targetlist, argv, qual) case 'd': res+=sprintf(res,"%d",*(int *)*argv++); break; - default: /* Swallow other %? pairs */ + default: break; } } else break; - } else *res++ = *fmt; /* text -> result buffer */ + } else *res++ = *fmt; } *res='\0'; - optimize_sql_stmt(result_buf); + if (qual) + res += sprintf(res, " WHERE %s", qual); + + if(sort) + res += sprintf(res, " ORDER BY %s", sort); + + result_buf = realloc(result_buf, strlen(result_buf)); + + return result_buf; } int do_update(q, argv, qual, action, actarg) @@ -693,8 +651,13 @@ int do_update(q, argv, qual, action, actarg) char *argv[], *qual, *actarg; int (*action)(); { - build_sql_stmt(stmt_buf,"UPDATE",q->tlist,argv,qual); - EXEC SQL EXECUTE IMMEDIATE :stmt_buf; + EXEC SQL BEGIN DECLARE SECTION; + char *stmt; + EXEC SQL END DECLARE SECTION; + + stmt = build_sql_stmt("UPDATE",q->tlist,argv,q->vcnt,qual,NULL); + EXEC SQL EXECUTE IMMEDIATE :stmt; + free(stmt); if (mr_errcode) return(mr_errcode); return(MR_SUCCESS); } @@ -704,8 +667,13 @@ int do_append(q, argv, pqual, action, actarg) char *argv[], *pqual, *actarg; int (*action)(); { - build_sql_stmt(stmt_buf,"INSERT",q->tlist,argv,pqual); - EXEC SQL EXECUTE IMMEDIATE :stmt_buf; + EXEC SQL BEGIN DECLARE SECTION; + char *stmt; + EXEC SQL END DECLARE SECTION; + + stmt = build_sql_stmt("INSERT",q->tlist,argv,q->vcnt,pqual,NULL); + EXEC SQL EXECUTE IMMEDIATE :stmt; + free(stmt); if (mr_errcode) return(mr_errcode); return(MR_SUCCESS); } diff --git a/server/qsupport.pc b/server/qsupport.pc index d6881099..dbae9311 100644 --- a/server/qsupport.pc +++ b/server/qsupport.pc @@ -110,7 +110,7 @@ int get_list_info(q, aargv, cl, action, actarg) client *cl; int (*action)(), actarg; { - char *argv[13]; + char *argv[13], *s, *d; EXEC SQL BEGIN DECLARE SECTION; char *name, acl_type[9], listname[33], active[5], public[5], hidden[5]; char maillist[5], grouplist[5], gid_str[6], desc[256]; @@ -121,12 +121,23 @@ int get_list_info(q, aargv, cl, action, actarg) struct save_queue *sq, *sq_create(); returned = rowcount = 0; - name = aargv[0]; - convert_wildcards(name); + + /* copy list name and fix wildcards */ + name = malloc(2 * strlen(aargv[0]) + 1); + for (s = aargv[0], d = name; *s; s++, d++) + switch (*s) { + case '*': *d = '%'; break; + case '?': *d = '_'; break; + case '%': + case '_': *d++ = '*'; /* fall through */ + default: *d = *s; break; + } + *d = '\0'; sq = sq_create(); EXEC SQL DECLARE csr102 CURSOR FOR SELECT list_id FROM list WHERE name LIKE :name ESCAPE '*'; + free(name); if (dbms_errno) return(mr_errcode); EXEC SQL OPEN csr102; diff --git a/server/queries2.c b/server/queries2.c index eeb9fa9c..abf6ba0e 100644 --- a/server/queries2.c +++ b/server/queries2.c @@ -170,26 +170,6 @@ int num_tables = 27; * can be shared. */ -static struct valobj VOwild0[] = { - {V_WILD, 0}, -}; - -static struct valobj VOupwild0[] = { - {V_UPWILD, 0}, -}; - -static struct valobj VOwild01[] = { - {V_WILD, 0}, - {V_WILD, 1}, -}; - -static struct valobj VOwild012[] = { - {V_WILD, 0}, - {V_WILD, 1}, - {V_WILD, 2}, -}; - - static struct valobj VOuser0[] = { {V_ID, 0, USERS_TABLE, LOGIN, USERS_ID, MR_USER}, }; @@ -225,45 +205,18 @@ static struct valobj VOchar0[] = { */ static struct validate VDmach = { VOmach0, 1 }; -static struct validate VDwild0= { VOwild0, 1 }; -static struct validate VDupwild0= { VOupwild0, 1 }; -static struct validate VDwild2 = { VOwild01,2 }; -static struct validate VDwild3 = { VOwild012,3 }; static struct validate VDfixmodby = { - 0 - 0, 0, 0, 0, 0, 0, 0, - followup_fix_modby, -}; - -static struct validate VDwildfixmodby = { - VOwild0, - 1, - 0, - 0, - 0, - 0, 0, 0, followup_fix_modby, }; -static struct validate VDupwildfixmodby = { - VOupwild0, - 1, - 0, - 0, - 0, - 0, - 0, - 0, - followup_fix_modby, -}; /* Query data */ @@ -285,8 +238,8 @@ static char *gubl_fields[] = { static struct validate gubl_validate = { - VOwild0, - 1, + 0, + 0, 0, 0, 0, @@ -310,8 +263,8 @@ static char *guan_fields[] = { static struct validate guan_validate = { - VOwild01, - 2, + 0, + 0, 0, 0, 0, @@ -364,8 +317,8 @@ static char *gubn_fields[] = { static struct validate gubn_validate = { - VOwild01, - 2, + 0, + 0, 0, 0, 0, @@ -796,16 +749,9 @@ static char *ghst_fields[] = { NAME, "vendor", "model", "os", "location", "contact", "use", "status", "status_change", "network", ADDRESS, ACE_TYPE, ACE_NAME, "admin_comment", "ops_comment", "created", "creator", "inuse", MOD1, MOD2, MOD3, }; -static struct valobj ghst_valobj[] = { - {V_UPWILD, 0}, - {V_UPWILD, 1}, - {V_UPWILD, 2}, - {V_UPWILD, 3}, -}; - static struct validate ghst_validate = { - ghst_valobj, - 4, + 0, + 0, 0, 0, 0, @@ -903,14 +849,9 @@ static char *ghal_fields[] = { ALIAS, "canonical_hostname" }; -static struct valobj ghal_valobj[] = { - {V_UPWILD, 0}, - {V_UPWILD, 1}, -}; - static struct validate ghal_validate = { - ghal_valobj, - 2, + 0, + 0, 0, 0, 0, @@ -922,13 +863,12 @@ static struct validate ghal_validate = { static struct valobj ahal_valobj[] = { {V_CHAR, 0, HOSTALIAS_TABLE, NAME}, - {V_UPWILD, 0}, {V_ID, 1, MACHINE_TABLE, NAME, MACH_ID, MR_MACHINE}, }; static struct validate ahal_validate = { ahal_valobj, - 3, + 2, NAME, "name = '%s'", 1, @@ -939,13 +879,12 @@ static struct validate ahal_validate = { }; static struct valobj dhal_valobj[] = { - {V_UPWILD, 0}, {V_ID, 1, MACHINE_TABLE, NAME, MACH_ID, MR_MACHINE}, }; static struct validate dhal_validate = { dhal_valobj, - 2, + 1, NAME, "name = '%s' AND mach_id = %d", 2, @@ -962,8 +901,8 @@ static char *gsnt_fields[] = { }; static struct validate gsnt_validate = { - VOupwild0, - 1, + 0, + 0, 0, 0, 0, @@ -1122,14 +1061,6 @@ static char *gmcm_fields[] = { MACHINE, CLUSTER, }; -static struct valobj gmcm_valobj[] = -{ - {V_UPWILD, 0}, - {V_WILD, 1}, -}; - -static struct validate gmcm_validate = { gmcm_valobj, 2 }; - static struct valobj amtc_valobj[] = /* ADD_MACHINE_TO_CLUSTER */ { /* DELETE_MACHINE_FROM_CLUSTER */ {V_ID, 0, MACHINE_TABLE, NAME, MACH_ID, MR_MACHINE}, @@ -1452,8 +1383,8 @@ static char *gsin_fields[] = { static struct validate gsin_validate = { - VOupwild0, - 1, + 0, + 0, 0, 0, 0, @@ -1574,14 +1505,9 @@ static char *gshi_fields[] = { "value3", MOD1, MOD2, MOD3, }; -static struct valobj gshi_valobj[] = { - { V_UPWILD, 0 }, - { V_UPWILD, 1 }, -}; - static struct validate gshi_validate = { - gshi_valobj, - 2, + 0, + 0, 0, 0, 0, @@ -1750,15 +1676,9 @@ static char *gfsn_fields[] = { "create", "lockertype", MOD1, MOD2, MOD3, }; -static struct valobj gfsn_valobj[] = -{ - {V_ID, 0, MACHINE_TABLE, NAME, MACH_ID, MR_MACHINE}, - {V_WILD, 1}, -}; - static struct validate gfsn_validate = { - gfsn_valobj, - 2, + VOmach0, + 1, 0, 0, 0, @@ -1913,14 +1833,9 @@ static char *gnfp_fields[] = { MACHINE, DIR, DEVICE, STATUS, "allocated", "size", MOD1, MOD2, MOD3, }; -static struct valobj gnfp_valobj[] = { - {V_ID, 0, MACHINE_TABLE, NAME, MACH_ID, MR_MACHINE}, - {V_WILD, 1}, -}; - static struct validate gnfp_validate = { - gnfp_valobj, - 2, + VOmach0, + 1, 0, 0, 0, @@ -2007,14 +1922,13 @@ static char *gqot_fields[] = { }; static struct valobj gqot_valobj[] = { - {V_WILD, 0}, {V_TYPE, 1, 0, QUOTA_TYPE, 0, MR_TYPE}, {V_TYPEDATA, 2, 0, 0, 0, MR_ACE}, }; static struct validate gqot_validate = { gqot_valobj, - 3, + 2, 0, 0, 0, @@ -2030,8 +1944,8 @@ static char *gqbf_fields[] = { }; static struct validate gqbf_validate = { - VOwild0, - 1, + 0, + 0, 0, 0, 0, @@ -2094,8 +2008,8 @@ static char *gnfq_fields[] = { }; static struct validate gnfq_validate = { - VOwild0, - 1, + 0, + 0, 0, 0, 0, @@ -2110,13 +2024,6 @@ static char *gnqp_fields[] = { FILESYS, LOGIN, QUOTA, DIR, MACHINE, MOD1, MOD2, MOD3, }; -static struct valobj gnqp_valobj[] = { - {V_ID, 0, MACHINE_TABLE, NAME, MACH_ID, MR_MACHINE}, - {V_WILD, 1}, -}; - -static struct validate gnqp_validate = { gnqp_valobj, 2, }; - static char *anfq_fields[] = { FILESYS, LOGIN, QUOTA, }; @@ -2170,8 +2077,8 @@ static char *gzcl_fields[] = { }; static struct validate gzcl_validate = { - VOwild0, - 1, + 0, + 0, 0, 0, 0, @@ -2258,8 +2165,8 @@ static char *gsha_fields[] = { static struct validate gsha_validate = { - VOupwild0, - 1, + 0, + 0, 0, 0, 0, @@ -2328,8 +2235,8 @@ static char *gpce_fields[] = { }; static struct validate gpce_validate = { - VOwild0, - 1, + 0, + 0, 0, 0, 0, @@ -2587,7 +2494,7 @@ struct query Queries2[] = { "u.login, u.unix_uid, u.shell, u.last, u.first, u.middle, u.status, u.clearid, u.type, str.string, u.signature, u.secure, TO_CHAR(u.modtime, 'DD-mon-YYYY HH24:MI:SS'), u.modby, u.modwith FROM users u, strings str", gual_fields, 15, - "u.login LIKE '%s' ESCAPE '*' AND u.users_id != 0 AND u.comments = str.string_id", + "u.login LIKE '%s' AND u.users_id != 0 AND u.comments = str.string_id", 1, "u.login", &gubl_validate, @@ -2619,7 +2526,7 @@ struct query Queries2[] = { "u.login, u.unix_uid, u.shell, u.last, u.first, u.middle, u.status, u.clearid, u.type, str.string, u.signature, u.secure, TO_CHAR(u.modtime, 'DD-mon-YYYY HH24:MI:SS'), u.modby, u.modwith FROM users u, strings str", guan_fields, 15, - "u.first LIKE '%s' ESCAPE '*' AND u.last LIKE '%s' ESCAPE '*' AND u.users_id != 0 and u.comments = str.string_id", + "u.first LIKE '%s' AND u.last LIKE '%s' AND u.users_id != 0 and u.comments = str.string_id", 2, "u.last, u.first", &guan_validate, @@ -2651,10 +2558,10 @@ struct query Queries2[] = { "u.login, u.unix_uid, u.shell, u.last, u.first, u.middle, u.status, u.clearid, u.type, str.string, u.signature, u.secure, TO_CHAR(u.modtime, 'DD-mon-YYYY HH24:MI:SS'), u.modby, u.modwith FROM users u, strings str", guam_fields, 15, - "u.clearid LIKE '%s' ESCAPE '*' AND u.users_id != 0 AND u.comments = str.string_id", + "u.clearid LIKE '%s' AND u.users_id != 0 AND u.comments = str.string_id", 1, "u.login", - &VDwildfixmodby, + &VDfixmodby, }, { @@ -2667,7 +2574,7 @@ struct query Queries2[] = { "u.login, u.unix_uid, u.shell, u.last, u.first, u.middle, u.status, u.clearid, u.type, TO_CHAR(u.modtime, 'DD-mon-YYYY HH24:MI:SS'), u.modby, u.modwith FROM users u", gubl_fields, 12, - "u.login LIKE '%s' ESCAPE '*' AND u.users_id != 0", + "u.login LIKE '%s' AND u.users_id != 0", 1, "u.login", &gubl_validate, @@ -2699,7 +2606,7 @@ struct query Queries2[] = { "u.login, u.unix_uid, u.shell, u.last, u.first, u.middle, u.status, u.clearid, u.type, TO_CHAR(u.modtime, 'DD-mon-YYYY HH24:MI:SS'), u.modby, u.modwith FROM users u", gubn_fields, 12, - "u.first LIKE '%s' ESCAPE '*' AND u.last LIKE '%s' ESCAPE '*' AND u.users_id != 0", + "u.first LIKE '%s' AND u.last LIKE '%s' AND u.users_id != 0", 2, "u.last, u.first", &gubn_validate, @@ -2731,10 +2638,10 @@ struct query Queries2[] = { "u.login, u.unix_uid, u.shell, u.last, u.first, u.middle, u.status, u.clearid, u.type, TO_CHAR(u.modtime, 'DD-mon-YYYY HH24:MI:SS'), u.modby, u.modwith FROM users u", gubm_fields, 12, - "u.clearid LIKE '%s' ESCAPE '*' AND u.users_id != 0", + "u.clearid LIKE '%s' AND u.users_id != 0", 1, "u.login", - &VDwildfixmodby, + &VDfixmodby, }, { @@ -2939,10 +2846,10 @@ struct query Queries2[] = { "u.login, str.string FROM krbmap km, users u, strings str", gkum_fields, 2, - "u.login LIKE '%s' ESCAPE '*' AND str.string LIKE '%s' ESCAPE '*' AND km.users_id = u.users_id AND km.string_id = str.string_id", + "u.login LIKE '%s' AND str.string LIKE '%s' AND km.users_id = u.users_id AND km.string_id = str.string_id", 2, "u.login", - &VDwild2, + 0, }, { @@ -3131,7 +3038,7 @@ struct query Queries2[] = { "m.name, m.vendor, m.model, m.os, m.location, m.contact, m.use, m.status, TO_CHAR(m.statuschange, 'DD-mon-YYYY HH24:MI:SS'), s.name, m.address, m.owner_type, m.owner_id, m.acomment, m.ocomment, TO_CHAR(m.created, 'DD-mon-YYYY HH24:MI:SS'), m.creator, TO_CHAR(m.inuse, 'DD-mon-YYYY HH24:MI:SS'), TO_CHAR(m.modtime, 'DD-mon-YYYY HH24:MI:SS'), m.modby, m.modwith FROM machine m, subnet s", ghst_fields, 21, - "m.name LIKE '%s' ESCAPE '*' AND m.address LIKE '%s' ESCAPE '*' AND m.location LIKE '%s' ESCAPE '*' AND s.name LIKE '%s' ESCAPE '*' AND m.mach_id != 0 AND s.snet_id = m.snet_id", + "m.name LIKE UPPER('%s') AND m.address LIKE '%s' AND m.location LIKE UPPER('%s') AND s.name LIKE UPPER('%s') AND m.mach_id != 0 AND s.snet_id = m.snet_id", 4, "m.name", &ghst_validate, @@ -3195,10 +3102,10 @@ struct query Queries2[] = { "name, vendor, TO_CHAR(modtime, 'DD-mon-YYYY HH24:MI:SS'), modby, modwith FROM machine", gmac_fields, 5, - "name LIKE '%s' ESCAPE '*' AND mach_id != 0", + "name LIKE UPPER('%s') AND mach_id != 0", 1, "m.name", - &VDupwildfixmodby, + &VDfixmodby, }, { @@ -3211,7 +3118,7 @@ struct query Queries2[] = { "a.name, m.name FROM hostalias a, machine m", ghal_fields, 2, - "m.mach_id = a.mach_id and a.name LIKE '%s' ESCAPE '*' AND m.name LIKE '%s' ESCAPE '*'", + "m.mach_id = a.mach_id and a.name LIKE UPPER('%s') AND m.name LIKE UPPER('%s')", 2, "m.name, a.name", &ghal_validate, @@ -3259,7 +3166,7 @@ struct query Queries2[] = { "name, description, saddr, mask, low, high, prefix, owner_type, owner_id, TO_CHAR(modtime, 'DD-mon-YYYY HH24:MI:SS'), modby, modwith FROM subnet", gsnt_fields, 12, - "name LIKE '%s' ESCAPE '*' and snet_id != 0", + "name LIKE UPPER('%s') and snet_id != 0", 1, "name", &gsnt_validate, @@ -3323,10 +3230,10 @@ struct query Queries2[] = { "name, description, location, TO_CHAR(modtime, 'DD-mon-YYYY HH24:MI:SS'), modby, modwith FROM clusters", gclu_fields, 6, - "name LIKE '%s' ESCAPE '*' AND clu_id != 0", + "name LIKE '%s' AND clu_id != 0", 1, "name", - &VDwildfixmodby, + &VDfixmodby, }, { @@ -3387,10 +3294,10 @@ struct query Queries2[] = { "m.name, c.name FROM machine m, clusters c, mcmap mcm", gmcm_fields, 2, - "m.name LIKE '%s' ESCAPE '*' AND c.name LIKE '%s' ESCAPE '*' AND mcm.clu_id = c.clu_id AND mcm.mach_id = m.mach_id", + "m.name LIKE UPPER('%s') AND c.name LIKE '%s' AND mcm.clu_id = c.clu_id AND mcm.mach_id = m.mach_id", 2, "m.name, c.name", - &gmcm_validate, + 0, }, { @@ -3435,10 +3342,10 @@ struct query Queries2[] = { "c.name, svc.serv_label, svc.serv_cluster FROM svc svc, clusters c", gcld_fields, 3, - "c.clu_id = svc.clu_id AND c.name LIKE '%s' ESCAPE '*' AND svc.serv_label LIKE '%s' ESCAPE '*'", + "c.clu_id = svc.clu_id AND c.name LIKE '%s' AND svc.serv_label LIKE '%s'", 2, "c.name, svc.serv_label, svc.serv_cluster", - &VDwild2, + 0, }, { @@ -3499,10 +3406,10 @@ struct query Queries2[] = { "name FROM list", glin_fields, 1, - "name LIKE '%s' ESCAPE '*' AND list_id != 0", + "name LIKE '%s' AND list_id != 0", 1, "name", - &VDwild0, + 0, }, { @@ -3691,7 +3598,7 @@ struct query Queries2[] = { "name, update_int, target_file, script, dfgen, dfcheck, type, enable, inprogress, harderror, errmsg, acl_type, acl_id, TO_CHAR(modtime, 'DD-mon-YYYY HH24:MI:SS'), modby, modwith FROM servers", gsin_fields, 16, - "name LIKE '%s' ESCAPE '*'", + "name LIKE UPPER('%s')", 1, "name", &gsin_validate, @@ -3803,7 +3710,7 @@ struct query Queries2[] = { "sh.service, m.name, sh.enable, sh.override, sh.success, sh.inprogress, sh.hosterror, sh.hosterrmsg, sh.ltt, sh.lts, sh.value1, sh.value2, sh.value3, TO_CHAR(sh.modtime, 'DD-mon-YYYY HH24:MI:SS'), sh.modby, sh.modwith FROM serverhosts sh, machine m", gshi_fields, 16, - "sh.service LIKE '%s' ESCAPE '*' AND m.name LIKE '%s' ESCAPE '*' AND m.mach_id = sh.mach_id", + "sh.service LIKE UPPER('%s') AND m.name LIKE UPPER('%s') AND m.mach_id = sh.mach_id", 2, 0, &gshi_validate, @@ -3931,10 +3838,10 @@ struct query Queries2[] = { "sh.service, m.name FROM serverhosts sh, machine m", gslo_fields, 2, - "sh.service LIKE '%s' ESCAPE '*' AND sh.mach_id = m.mach_id", + "sh.service LIKE UPPER('%s') AND sh.mach_id = m.mach_id", 1, "sh.service, m.name", - &VDupwild0, + 0, }, { @@ -3947,10 +3854,10 @@ struct query Queries2[] = { "fs.label, fs.type, m.name, fs.name, fs.mount, fs.rwaccess, fs.comments, u.login, l.name, fs.createflg, fs.lockertype, TO_CHAR(fs.modtime, 'DD-mon-YYYY HH24:MI:SS'), fs.modby, fs.modwith FROM filesys fs, machine m, users u, list l", gfsl_fields, 14, - "fs.label LIKE '%s' ESCAPE '*' AND fs.mach_id = m.mach_id AND fs.owner = u.users_id AND fs.owners = l.list_id", + "fs.label LIKE '%s' AND fs.mach_id = m.mach_id AND fs.owner = u.users_id AND fs.owners = l.list_id", 1, "fs.label", - &VDwildfixmodby, + &VDfixmodby, }, { @@ -3979,7 +3886,7 @@ struct query Queries2[] = { "fs.label, fs.type, m.name, fs.name, fs.mount, fs.rwaccess, fs.comments, u.login, l.name, fs.createflg, fs.lockertype, TO_CHAR(fs.modtime, 'DD-mon-YYYY HH24:MI:SS'), fs.modby, fs.modwith FROM filesys fs, machine m, users u, list l, nfsphys np", gfsn_fields, 14, - "fs.mach_id = %d AND m.mach_id = fs.mach_id AND fs.owner = u.users_id AND fs.owners = l.list_id AND np.nfsphys_id = fs.phys_id AND np.dir LIKE '%s' ESCAPE '*' AND fs.type = 'NFS'", + "fs.mach_id = %d AND m.mach_id = fs.mach_id AND fs.owner = u.users_id AND fs.owners = l.list_id AND np.nfsphys_id = fs.phys_id AND np.dir LIKE '%s' AND fs.type = 'NFS'", 2, "fs.label", &gfsn_validate, @@ -4011,10 +3918,10 @@ struct query Queries2[] = { "fs.label, fs.type, m.name, fs.name, fs.mount, fs.rwaccess, fs.comments, u.login, l.name, fs.createflg, fs.lockertype, TO_CHAR(fs.modtime, 'DD-mon-YYYY HH24:MI:SS'), fs.modby, fs.modwith FROM filesys fs, machine m, users u, list l", gfsp_fields, 14, - "fs.name LIKE '%s' ESCAPE '*' AND m.mach_id = fs.mach_id AND fs.owner = u.users_id AND fs.owners = list_id", + "fs.name LIKE '%s' AND m.mach_id = fs.mach_id AND fs.owner = u.users_id AND fs.owners = list_id", 1, "fs.label", - &VDwildfixmodby, + &VDfixmodby, }, { @@ -4139,7 +4046,7 @@ struct query Queries2[] = { "m.name, np.dir, np.device, np.status, np.allocated, np.partsize, TO_CHAR(np.modtime, 'DD-mon-YYYY HH24:MI:SS'), np.modby, np.modwith FROM nfsphys np, machine m", gnfp_fields, 9, - "np.mach_id = %d AND np.dir LIKE '%s' ESCAPE '*' AND m.mach_id = np.mach_id", + "np.mach_id = %d AND np.dir LIKE '%s' AND m.mach_id = np.mach_id", 2, "m.name, np.dir", &gnfp_validate, @@ -4219,7 +4126,7 @@ struct query Queries2[] = { "fs.label, q.type, q.entity_id, q.quota, q.phys_id, m.name, TO_CHAR(q.modtime, 'DD-mon-YYYY HH24:MI:SS'), q.modby, q.modwith FROM quota q, filesys fs, machine m", gqot_fields, 9, - "fs.label LIKE '%s' ESCAPE '*' AND q.type = '%s' AND q.entity_id = %d AND fs.filsys_id = q.filsys_id AND m.mach_id = fs.mach_id", + "fs.label LIKE '%s' AND q.type = '%s' AND q.entity_id = %d AND fs.filsys_id = q.filsys_id AND m.mach_id = fs.mach_id", 3, "fs.label", &gqot_validate, @@ -4235,7 +4142,7 @@ struct query Queries2[] = { "fs.label, q.type, q.entity_id, q.quota, q.phys_id, m.name, TO_CHAR(q.modtime, 'DD-mon-YYYY HH24:MI:SS'), q.modby, q.modwith FROM quota q, filesys fs, machine m", gqbf_fields, 9, - "fs.label LIKE '%s' ESCAPE '*' AND fs.filsys_id = q.filsys_id AND m.mach_id = fs.mach_id", + "fs.label LIKE '%s' AND fs.filsys_id = q.filsys_id AND m.mach_id = fs.mach_id", 1, "fs.label, q.type", &gqbf_validate, @@ -4299,7 +4206,7 @@ struct query Queries2[] = { "fs.label, u.login, q.quota, q.phys_id, m.name, TO_CHAR(q.modtime, 'DD-mon-YYYY HH24:MI:SS'), q.modby, q.modwith FROM quota q, filesys fs, users u, machine m", gnfq_fields, 8, - "fs.label LIKE '%s' ESCAPE '*' AND q.type = 'USER' AND q.entity_id = u.users_id AND fs.filsys_id = q.filsys_id AND m.mach_id = fs.mach_id AND u.login = '%s'", + "fs.label LIKE '%s' AND q.type = 'USER' AND q.entity_id = u.users_id AND fs.filsys_id = q.filsys_id AND m.mach_id = fs.mach_id AND u.login = '%s'", 2, "fs.label, u.login", &gnfq_validate, @@ -4315,10 +4222,10 @@ struct query Queries2[] = { "fs.label, u.login, q.quota, np.dir, m.name FROM quota q, filesys fs, users u, nfsphys np, machine m", gnqp_fields, 5, - "np.mach_id = %d AND np.dir LIKE '%s' ESCAPE '*' AND q.phys_id = np.nfsphys_id AND fs.filsys_id = q.filsys_id AND q.type = 'USER' AND u.users_id = q.entity_id AND m.mach_id = np.mach_id", + "np.mach_id = %d AND np.dir LIKE '%s' AND q.phys_id = np.nfsphys_id AND fs.filsys_id = q.filsys_id AND q.type = 'USER' AND u.users_id = q.entity_id AND m.mach_id = np.mach_id", 2, "fs.label, np.dir, u.login", - &gnqp_validate, + 0, }, { @@ -4379,7 +4286,7 @@ struct query Queries2[] = { "class, xmt_type, xmt_id, sub_type, sub_id, iws_type, iws_id, iui_type, iui_id, TO_CHAR(modtime, 'DD-mon-YYYY HH24:MI:SS'), modby, modwith FROM zephyr", gzcl_fields, 12, - "class LIKE '%s' ESCAPE '*'", + "class LIKE '%s'", 1, "class", &gzcl_validate, @@ -4443,7 +4350,7 @@ struct query Queries2[] = { "m.name, ha.acl_type, ha.acl_id, TO_CHAR(ha.modtime, 'DD-mon-YYYY HH24:MI:SS'), ha.modby, ha.modwith FROM hostaccess ha, machine m", gsha_fields, 6, - "m.name LIKE '%s' ESCAPE '*' AND ha.mach_id = m.mach_id", + "m.name LIKE UPPER('%s') AND ha.mach_id = m.mach_id", 1, "m.name", &gsha_validate, @@ -4507,10 +4414,10 @@ struct query Queries2[] = { "name, protocol, port, description, TO_CHAR(modtime, 'DD-mon-YYYY HH24:MI:SS'), modby, modwith FROM services", gsvc_fields, 7, - "name LIKE '%s' ESCAPE '*'", + "name LIKE '%s'", 1, "name, protocol", - &VDwildfixmodby, + &VDfixmodby, }, { @@ -4555,7 +4462,7 @@ struct query Queries2[] = { "pc.name, m.name, pc.dir, pc.rp, pc.quotaserver, pc.auth, pc.price, pc.comments, TO_CHAR(pc.modtime, 'DD-mon-YYYY HH24:MI:SS'), pc.modby, pc.modwith FROM printcap pc, machine m", gpce_fields, 11, - "pc.name LIKE '%s' ESCAPE '*' AND m.mach_id = pc.mach_id", + "pc.name LIKE '%s' AND m.mach_id = pc.mach_id", 1, "pc.name", &gpce_validate, @@ -4603,10 +4510,10 @@ struct query Queries2[] = { "pc.name, m.name, pc.dir, pc.rp, pc.comments, TO_CHAR(pc.modtime, 'DD-mon-YYYY HH24:MI:SS'), pc.modby, pc.modwith FROM printcap pc, machine m", gpcp_fields, 8, - "pc.name LIKE '%s' ESCAPE '*' AND m.mach_id = pc.mach_id", + "pc.name LIKE '%s' AND m.mach_id = pc.mach_id", 1, "pc.name", - &VDwildfixmodby, + &VDfixmodby, }, { @@ -4635,10 +4542,10 @@ struct query Queries2[] = { "pal.name, pal.identifier, m.name, TO_CHAR(pal.modtime, 'DD-mon-YYYY HH24:MI:SS'), pal.modby, pal.modwith FROM palladium pal, machine m", gpdm_fields, 6, - "pal.name LIKE '%s' ESCAPE '*' AND m.mach_id = pal.mach_id", + "pal.name LIKE '%s' AND m.mach_id = pal.mach_id", 1, "pal.name", - &VDwildfixmodby, + &VDfixmodby, }, { @@ -4683,10 +4590,10 @@ struct query Queries2[] = { "name, type, trans FROM alias", gali_fields, 3, - "name LIKE '%s' ESCAPE '*' AND type LIKE '%s' ESCAPE '*' AND trans LIKE '%s' ESCAPE '*'", + "name LIKE '%s' AND type LIKE '%s' AND trans LIKE '%s'", 3, "name, type, trans", - &VDwild3, + 0, }, { diff --git a/server/query.h b/server/query.h index ad6bf54b..4f8d5ddf 100644 --- a/server/query.h +++ b/server/query.h @@ -55,9 +55,8 @@ struct validate }; /* Validated Object Types */ -enum vo_type {V_NAME, V_ID, V_TYPE, V_TYPEDATA, - V_RENAME, V_CHAR, V_WILD, V_UPWILD, - V_LEN, V_NUM}; +enum vo_type {V_NAME, V_ID, V_TYPE, V_TYPEDATA, V_RENAME, + V_CHAR, V_LEN, V_NUM}; /* Validated Object Definition */ struct valobj diff --git a/server/qvalidate.pc b/server/qvalidate.pc index f40f19a8..3372e5d7 100644 --- a/server/qvalidate.pc +++ b/server/qvalidate.pc @@ -38,7 +38,6 @@ int validate_type(char *argv[], struct valobj *vo); int validate_typedata(struct query *, char *argv[], struct valobj *vo); int validate_len(char *argv[], struct valobj *vo); int validate_num(char *argv[], struct valobj *vo); -int convert_wildcards_uppercase(char *arg); extern SQLDA *sqlald(int,int,int); @@ -51,13 +50,11 @@ int validate_row(q, argv, v) char *argv[]; register struct validate *v; { - EXEC SQL BEGIN DECLARE SECTION; - char qual[128]; + char *qual; int rowcount; - EXEC SQL END DECLARE SECTION; /* build where clause */ - build_qual(v->qual, v->argc, argv, qual); + qual = build_qual(v->qual, v->argc, argv); if (log_flags & LOG_VALID) /* tell the logfile what we're doing */ @@ -66,6 +63,7 @@ int validate_row(q, argv, v) /* look for the record */ sprintf(stmt_buf,"SELECT COUNT (*) FROM %s WHERE %s", table_name[q->rtable],qual); + free(qual); dosql(sqlbuffer); if (dbms_errno) return(mr_errcode); @@ -137,15 +135,6 @@ int validate_fields(q, argv, vo, n) com_err(whoami, 0, "validating number: %s", argv[vo->index]); status = validate_num(argv, vo); break; - - case V_WILD: - status = convert_wildcards(argv[vo->index]); - break; - - case V_UPWILD: - status = convert_wildcards_uppercase(argv[vo->index]); - break; - } if (status != MR_EXISTS) return(status); @@ -519,60 +508,6 @@ SQLDA *mr_alloc_sqlda() return it; } - -/* Convert normal Unix-style wildcards to SQL voodoo */ -int convert_wildcards(arg) - char *arg; -{ - static char buffer[ARGLEN]; - register char *s, *d; - - for(d=buffer,s=arg;*s;s++) { - switch(*s) { - case '*': *d++='%'; *d++='%'; break; - case '?': *d++='_'; break; - case '_': *d++='*'; *d++ = *s; break; - case '%': *d++='*'; *d++='%'; *d++='%'; break; - default: *d++ = *s; break; - } - } - *d='\0'; - - /* Copy back into argv */ - strcpy(arg,buffer); - - return(MR_EXISTS); -} - -/* This version includes uppercase conversion, for things like gmac. - * This is necessary because "LIKE" doesn't work with "uppercase()". - * Including it in a wildcard routine saves making two passes over - * the argument string. - */ -int convert_wildcards_uppercase(arg) - char *arg; -{ - static char buffer[ARGLEN]; - register char *s, *d; - - for(d=buffer,s=arg;*s;s++) { - switch(*s) { - case '*': *d++='%'; *d++='%'; break; - case '?': *d++='_'; break; - case '_': *d++='*'; *d++ = *s; break; - case '%': *d++='*'; *d++='%'; *d++='%'; break; - default: *d++=toupper(*s); break; /* This is the only diff. */ - } - } - *d='\0'; - - /* Copy back into argv */ - strcpy(arg,buffer); - - return(MR_EXISTS); -} - - /* Adds a string to the string table. Returns the id number. * */ -- 2.45.1