11d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich/* lookup_table.c -- 21d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich * Copyright 2009 Red Hat Inc., Durham, North Carolina. 31d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich * All Rights Reserved. 41d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich * 51d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich * This library is free software; you can redistribute it and/or 61d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich * modify it under the terms of the GNU Lesser General Public 71d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich * License as published by the Free Software Foundation; either 81d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich * version 2.1 of the License, or (at your option) any later version. 91d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich * 101d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich * This library is distributed in the hope that it will be useful, 111d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich * but WITHOUT ANY WARRANTY; without even the implied warranty of 121d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 131d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich * Lesser General Public License for more details. 141d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich * 151d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich * You should have received a copy of the GNU Lesser General Public 161d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich * License along with this library; if not, write to the Free Software 171d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 181d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich * 191d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich * Authors: 201d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich * Steve Grubb <sgrubb@redhat.com> 211d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich */ 221d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 231d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#include "config.h" 241d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#include <stddef.h> 251d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#include <linux/capability.h> 261d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#include <strings.h> 271d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 281d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 291d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#ifndef CAP_LAST_CAP 301d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#define CAP_LAST_CAP CAP_AUDIT_CONTROL 311d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#endif 321d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#undef cap_valid 331d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#define cap_valid(x) ((x) <= CAP_LAST_CAP) 341d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 351d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 361d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevichstruct transtab { 371d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich int value; 381d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich int offset; 391d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich}; 401d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 411d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#define MSGSTRFIELD(line) MSGSTRFIELD1(line) 421d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#define MSGSTRFIELD1(line) str##line 431d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 441d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 451d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich/* To create the following tables in a DSO-friendly way we split them in 461d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich two separate variables: a long string which is created by concatenating 471d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich all strings referenced in the table and the table itself, which uses 481d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich offsets instead of string pointers. To do this without increasing 491d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich the maintenance burden we use a lot of preprocessor magic. All the 501d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich maintainer has to do is to add a new entry to the included file and 511d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich recompile. */ 521d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 531d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevichstatic const union captab_msgstr_t { 541d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich struct { 551d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#define _S(n, s) char MSGSTRFIELD(__LINE__)[sizeof (s)]; 561d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#include "captab.h" 571d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#undef _S 581d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich }; 591d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich char str[0]; 601d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich} captab_msgstr = { { 611d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#define _S(n, s) s, 621d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#include "captab.h" 631d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#undef _S 641d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich} }; 651d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevichstatic const struct transtab captab[] = { 661d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#define _S(n, s) { n, offsetof(union captab_msgstr_t, \ 671d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich MSGSTRFIELD(__LINE__)) }, 681d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#include "captab.h" 691d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#undef _S 701d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich}; 711d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#define CAP_NG_CAPABILITY_NAMES (sizeof(captab)/sizeof(captab[0])) 721d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 731d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 741d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 751d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 761d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevichstatic int capng_lookup_name(const struct transtab *table, 771d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich const char *tabstr, size_t length, const char *name) 781d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich{ 791d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich size_t i; 801d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 811d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich for (i = 0; i < length; i++) { 821d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (!strcasecmp(tabstr + table[i].offset, name)) 831d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich return table[i].value; 841d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich } 851d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich return -1; 861d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich} 871d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 881d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevichstatic const char *capng_lookup_number(const struct transtab *table, 891d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich const char *tabstr, size_t length, 901d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich int number) 911d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich{ 921d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich size_t i; 931d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 941d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich for (i = 0; i < length; i++) { 951d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (table[i].value == number) 961d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich return tabstr + table[i].offset; 971d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich } 981d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich return NULL; 991d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich} 1001d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 1011d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevichint capng_name_to_capability(const char *name) 1021d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich{ 1031d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich return capng_lookup_name(captab, captab_msgstr.str, 1041d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich CAP_NG_CAPABILITY_NAMES, name); 1051d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich} 1061d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 1071d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevichconst char *capng_capability_to_name(unsigned int capability) 1081d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich{ 1091d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich if (!cap_valid(capability)) 1101d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich return NULL; 1111d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 1121d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich return capng_lookup_number(captab, captab_msgstr.str, 1131d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich CAP_NG_CAPABILITY_NAMES, capability); 1141d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich} 1151d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich 116