| 6312 | */ |
| 6313 | |
| 6314 | bool check_grant_db(THD *thd,const char *db) |
| 6315 | { |
| 6316 | Security_context *sctx= thd->security_ctx; |
| 6317 | char helping [NAME_LEN+USERNAME_LENGTH+2], *end; |
| 6318 | uint len; |
| 6319 | bool error= TRUE; |
| 6320 | size_t copy_length; |
| 6321 | |
| 6322 | copy_length= (size_t) (strlen(sctx->priv_user) + |
| 6323 | strlen(db ? db : "")) + 1; /* Added 1 at the end to avoid |
| 6324 | buffer overflow at strmov()*/ |
| 6325 | |
| 6326 | /* |
| 6327 | Make sure that strmov() operations do not result in buffer overflow. |
| 6328 | */ |
| 6329 | if (copy_length >= (NAME_LEN+USERNAME_LENGTH+2)) |
| 6330 | return 1; |
| 6331 | |
| 6332 | end= strmov(helping, sctx->priv_user) + 1; |
| 6333 | end= strnmov(end, db, helping + sizeof(helping) - end); |
| 6334 | |
| 6335 | if (end >= helping + sizeof(helping)) // db name was truncated |
| 6336 | return 1; // no privileges for an invalid db name |
| 6337 | |
| 6338 | len= (uint) (end - helping) + 1; |
| 6339 | |
| 6340 | mysql_rwlock_rdlock(&LOCK_grant); |
| 6341 | |
| 6342 | for (uint idx=0 ; idx < column_priv_hash.records ; idx++) |
| 6343 | { |
| 6344 | GRANT_TABLE *grant_table= (GRANT_TABLE*) |
| 6345 | my_hash_element(&column_priv_hash, |
| 6346 | idx); |
| 6347 | if (len < grant_table->key_length && |
| 6348 | !memcmp(grant_table->hash_key,helping,len) && |
| 6349 | grant_table->host.compare_hostname(sctx->get_host()->ptr(), |
| 6350 | sctx->get_ip()->ptr())) |
| 6351 | { |
| 6352 | error= FALSE; /* Found match. */ |
| 6353 | break; |
| 6354 | } |
| 6355 | } |
| 6356 | |
| 6357 | if (error) |
| 6358 | error= check_grant_db_routine(thd, db, &proc_priv_hash) && |
| 6359 | check_grant_db_routine(thd, db, &func_priv_hash); |
| 6360 | |
| 6361 | mysql_rwlock_unlock(&LOCK_grant); |
| 6362 | |
| 6363 | return error; |
| 6364 | } |
| 6365 | |
| 6366 | |
| 6367 | /**************************************************************************** |
nothing calls this directly
no test coverage detected