LCOV - code coverage report
Current view: top level - util - sss_semanage.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 233 0.0 %
Date: 2016-06-29 Functions: 0 8 0.0 %

          Line data    Source code
       1             : /*
       2             :    SSSD
       3             : 
       4             :    sss_semanage.c
       5             : 
       6             :    Copyright (C) Jakub Hrozek <jhrozek@redhat.com>        2010
       7             : 
       8             :    This program is free software; you can redistribute it and/or modify
       9             :    it under the terms of the GNU General Public License as published by
      10             :    the Free Software Foundation; either version 3 of the License, or
      11             :    (at your option) any later version.
      12             : 
      13             :    This program is distributed in the hope that it will be useful,
      14             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      16             :    GNU General Public License for more details.
      17             : 
      18             :    You should have received a copy of the GNU General Public License
      19             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      20             : */
      21             : 
      22             : #include "config.h"
      23             : 
      24             : #include <stdio.h>
      25             : #ifdef HAVE_SEMANAGE
      26             : #include <semanage/semanage.h>
      27             : #endif
      28             : 
      29             : #include "util/util.h"
      30             : 
      31             : #ifndef DEFAULT_SERANGE
      32             : #define DEFAULT_SERANGE "s0"
      33             : #endif
      34             : 
      35             : #ifdef HAVE_SEMANAGE
      36             : /* turn libselinux messages into SSSD DEBUG() calls */
      37           0 : static void sss_semanage_error_callback(void *varg,
      38             :                                         semanage_handle_t *handle,
      39             :                                         const char *fmt, ...)
      40             : {
      41           0 :     int level = SSSDBG_INVALID;
      42             :     va_list ap;
      43             : 
      44           0 :     switch (semanage_msg_get_level(handle)) {
      45             :         case SEMANAGE_MSG_ERR:
      46           0 :             level = SSSDBG_CRIT_FAILURE;
      47           0 :             break;
      48             :         case SEMANAGE_MSG_WARN:
      49           0 :             level = SSSDBG_MINOR_FAILURE;
      50           0 :             break;
      51             :         case SEMANAGE_MSG_INFO:
      52           0 :             level = SSSDBG_TRACE_FUNC;
      53           0 :             break;
      54             :     }
      55             : 
      56           0 :     va_start(ap, fmt);
      57           0 :     if (DEBUG_IS_SET(level)) {
      58           0 :         sss_vdebug_fn(__FILE__, __LINE__, "libsemanage", level, 0, fmt, ap);
      59             :     }
      60           0 :     va_end(ap);
      61           0 : }
      62             : 
      63           0 : static void sss_semanage_close(semanage_handle_t *handle)
      64             : {
      65           0 :     if (handle == NULL) {
      66           0 :         return;     /* semanage uses asserts */
      67             :     }
      68             : 
      69           0 :     if (semanage_is_connected(handle)) {
      70           0 :         semanage_disconnect(handle);
      71             :     }
      72           0 :     semanage_handle_destroy(handle);
      73             : }
      74             : 
      75           0 : static semanage_handle_t *sss_semanage_init(void)
      76             : {
      77             :     int ret;
      78           0 :     semanage_handle_t *handle = NULL;
      79             : 
      80           0 :     handle = semanage_handle_create();
      81           0 :     if (!handle) {
      82           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Cannot create SELinux management handle\n");
      83           0 :         return NULL;
      84             :     }
      85             : 
      86           0 :     semanage_msg_set_callback(handle,
      87             :                               sss_semanage_error_callback,
      88             :                               NULL);
      89             : 
      90           0 :     ret = semanage_is_managed(handle);
      91           0 :     if (ret != 1) {
      92           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "SELinux policy not managed\n");
      93           0 :         goto fail;
      94             :     }
      95             : 
      96           0 :     ret = semanage_access_check(handle);
      97           0 :     if (ret < SEMANAGE_CAN_READ) {
      98           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Cannot read SELinux policy store\n");
      99           0 :         goto fail;
     100             :     }
     101             : 
     102           0 :     ret = semanage_connect(handle);
     103           0 :     if (ret != 0) {
     104           0 :         DEBUG(SSSDBG_CRIT_FAILURE,
     105             :               "Cannot estabilish SELinux management connection\n");
     106           0 :         goto fail;
     107             :     }
     108             : 
     109           0 :     return handle;
     110             : fail:
     111           0 :     sss_semanage_close(handle);
     112           0 :     return NULL;
     113             : }
     114             : 
     115           0 : static int sss_semanage_user_add(semanage_handle_t *handle,
     116             :                                  semanage_seuser_key_t *key,
     117             :                                  const char *login_name,
     118             :                                  const char *seuser_name,
     119             :                                  const char *mls)
     120             : {
     121             :     int ret;
     122           0 :     semanage_seuser_t *seuser = NULL;
     123             : 
     124           0 :     ret = semanage_seuser_create(handle, &seuser);
     125           0 :     if (ret != 0) {
     126           0 :         DEBUG(SSSDBG_CRIT_FAILURE,
     127             :               "Cannot create SELinux login mapping for %s\n", login_name);
     128           0 :         ret = EIO;
     129           0 :         goto done;
     130             :     }
     131             : 
     132           0 :     ret = semanage_seuser_set_name(handle, seuser, login_name);
     133           0 :     if (ret != 0) {
     134           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Could not set name for %s\n", login_name);
     135           0 :         ret = EIO;
     136           0 :         goto done;
     137             :     }
     138             : 
     139           0 :     ret = semanage_seuser_set_mlsrange(handle, seuser,
     140             :                                        mls ? mls : DEFAULT_SERANGE);
     141           0 :     if (ret != 0) {
     142           0 :         DEBUG(SSSDBG_CRIT_FAILURE,
     143             :               "Could not set serange for %s\n", login_name);
     144           0 :         ret = EIO;
     145           0 :         goto done;
     146             :     }
     147             : 
     148           0 :     ret = semanage_seuser_set_sename(handle, seuser, seuser_name);
     149           0 :     if (ret != 0) {
     150           0 :         DEBUG(SSSDBG_CRIT_FAILURE,
     151             :               "Could not set SELinux user for %s\n", login_name);
     152           0 :         ret = EIO;
     153           0 :         goto done;
     154             :     }
     155             : 
     156           0 :     ret = semanage_seuser_modify_local(handle, key, seuser);
     157           0 :     if (ret != 0) {
     158           0 :         DEBUG(SSSDBG_CRIT_FAILURE,
     159             :               "Could not add login mapping for %s\n", login_name);
     160           0 :         ret = EIO;
     161           0 :         goto done;
     162             :     }
     163             : 
     164           0 :     ret = EOK;
     165             : done:
     166           0 :     semanage_seuser_free(seuser);
     167           0 :     return ret;
     168             : }
     169             : 
     170           0 : static int sss_semanage_user_mod(semanage_handle_t *handle,
     171             :                                  semanage_seuser_key_t *key,
     172             :                                  const char *login_name,
     173             :                                  const char *seuser_name,
     174             :                                  const char *mls)
     175             : {
     176             :     int ret;
     177           0 :     semanage_seuser_t *seuser = NULL;
     178             : 
     179           0 :     semanage_seuser_query(handle, key, &seuser);
     180           0 :     if (seuser == NULL) {
     181           0 :         DEBUG(SSSDBG_CRIT_FAILURE,
     182             :               "Could not query seuser for %s\n", login_name);
     183           0 :         ret = EIO;
     184           0 :         goto done;
     185             :     }
     186             : 
     187           0 :     ret = semanage_seuser_set_mlsrange(handle, seuser,
     188             :                                        mls ? mls : DEFAULT_SERANGE);
     189           0 :     if (ret != 0) {
     190           0 :         DEBUG(SSSDBG_CRIT_FAILURE,
     191             :               "Could not set serange for %s\n", login_name);
     192           0 :         ret = EIO;
     193           0 :         goto done;
     194             :     }
     195             : 
     196           0 :     ret = semanage_seuser_set_sename(handle, seuser, seuser_name);
     197           0 :     if (ret != 0) {
     198           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Could not set sename for %s\n", login_name);
     199           0 :         ret = EIO;
     200           0 :         goto done;
     201             :     }
     202             : 
     203           0 :     ret = semanage_seuser_modify_local(handle, key, seuser);
     204           0 :     if (ret != 0) {
     205           0 :         DEBUG(SSSDBG_CRIT_FAILURE,
     206             :               "Could not modify login mapping for %s\n", login_name);
     207           0 :         ret = EIO;
     208           0 :         goto done;
     209             :     }
     210             : 
     211           0 :     ret = EOK;
     212             : done:
     213           0 :     semanage_seuser_free(seuser);
     214           0 :     return ret;
     215             : }
     216             : 
     217           0 : int set_seuser(const char *login_name, const char *seuser_name,
     218             :                const char *mls)
     219             : {
     220           0 :     semanage_handle_t *handle = NULL;
     221           0 :     semanage_seuser_key_t *key = NULL;
     222             :     int ret;
     223           0 :     int seuser_exists = 0;
     224             : 
     225           0 :     if (seuser_name == NULL) {
     226             :         /* don't care, just let system pick the defaults */
     227           0 :         return EOK;
     228             :     }
     229             : 
     230           0 :     handle = sss_semanage_init();
     231           0 :     if (!handle) {
     232           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Cannot init SELinux management\n");
     233           0 :         ret = EIO;
     234           0 :         goto done;
     235             :     }
     236             : 
     237           0 :     ret = semanage_begin_transaction(handle);
     238           0 :     if (ret != 0) {
     239           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Cannot begin SELinux transaction\n");
     240           0 :         ret = EIO;
     241           0 :         goto done;
     242             :     }
     243             : 
     244           0 :     ret = semanage_seuser_key_create(handle, login_name, &key);
     245           0 :     if (ret != 0) {
     246           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Cannot create SELinux user key\n");
     247           0 :         ret = EIO;
     248           0 :         goto done;
     249             :     }
     250             : 
     251           0 :     ret = semanage_seuser_exists(handle, key, &seuser_exists);
     252           0 :     if (ret < 0) {
     253           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Cannot verify the SELinux user\n");
     254           0 :         ret = EIO;
     255           0 :         goto done;
     256             :     }
     257             : 
     258           0 :     if (seuser_exists) {
     259           0 :         ret = sss_semanage_user_mod(handle, key, login_name, seuser_name,
     260             :                                     mls);
     261           0 :         if (ret != 0) {
     262           0 :             DEBUG(SSSDBG_CRIT_FAILURE, "Cannot modify SELinux user mapping\n");
     263           0 :             ret = EIO;
     264           0 :             goto done;
     265             :         }
     266             :     } else {
     267           0 :         ret = sss_semanage_user_add(handle, key, login_name, seuser_name,
     268             :                                     mls);
     269           0 :         if (ret != 0) {
     270           0 :             DEBUG(SSSDBG_CRIT_FAILURE, "Cannot add SELinux user mapping\n");
     271           0 :             ret = EIO;
     272           0 :             goto done;
     273             :         }
     274             :     }
     275             : 
     276           0 :     ret = semanage_commit(handle);
     277           0 :     if (ret < 0) {
     278           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Cannot commit SELinux transaction\n");
     279           0 :         ret = EIO;
     280           0 :         goto done;
     281             :     }
     282             : 
     283           0 :     ret = EOK;
     284             : done:
     285           0 :     semanage_seuser_key_free(key);
     286           0 :     sss_semanage_close(handle);
     287           0 :     return ret;
     288             : }
     289             : 
     290           0 : int del_seuser(const char *login_name)
     291             : {
     292           0 :     semanage_handle_t *handle = NULL;
     293           0 :     semanage_seuser_key_t *key = NULL;
     294             :     int ret;
     295           0 :     int exists = 0;
     296             : 
     297           0 :     handle = sss_semanage_init();
     298           0 :     if (!handle) {
     299           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Cannot init SELinux management\n");
     300           0 :         ret = EIO;
     301           0 :         goto done;
     302             :     }
     303             : 
     304           0 :     ret = semanage_begin_transaction(handle);
     305           0 :     if (ret != 0) {
     306           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Cannot begin SELinux transaction\n");
     307           0 :         ret = EIO;
     308           0 :         goto done;
     309             :     }
     310             : 
     311           0 :     ret = semanage_seuser_key_create(handle, login_name, &key);
     312           0 :     if (ret != 0) {
     313           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Cannot create SELinux user key\n");
     314           0 :         ret = EIO;
     315           0 :         goto done;
     316             :     }
     317             : 
     318           0 :     ret = semanage_seuser_exists(handle, key, &exists);
     319           0 :     if (ret < 0) {
     320           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Cannot verify the SELinux user\n");
     321           0 :         ret = EIO;
     322           0 :         goto done;
     323             :     }
     324             : 
     325           0 :     if (!exists) {
     326           0 :         DEBUG(SSSDBG_FUNC_DATA,
     327             :               "Login mapping for %s is not defined, OK if default mapping "
     328             :                   "was used\n", login_name);
     329           0 :         ret = EOK;  /* probably default mapping */
     330           0 :         goto done;
     331             :     }
     332             : 
     333           0 :     ret = semanage_seuser_exists_local(handle, key, &exists);
     334           0 :     if (ret < 0) {
     335           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Cannot verify the SELinux user\n");
     336           0 :         ret = EIO;
     337           0 :         goto done;
     338             :     }
     339             : 
     340           0 :     if (!exists) {
     341           0 :         DEBUG(SSSDBG_CRIT_FAILURE,
     342             :               "Login mapping for %s is defined in policy, cannot be deleted\n",
     343             :               login_name);
     344           0 :         ret = ENOENT;
     345           0 :         goto done;
     346             :     }
     347             : 
     348           0 :     ret = semanage_seuser_del_local(handle, key);
     349           0 :     if (ret != 0) {
     350           0 :         DEBUG(SSSDBG_CRIT_FAILURE,
     351             :               "Could not delete login mapping for %s\n", login_name);
     352           0 :         ret = EIO;
     353           0 :         goto done;
     354             :     }
     355             : 
     356           0 :     ret = semanage_commit(handle);
     357           0 :     if (ret < 0) {
     358           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Cannot commit SELinux transaction\n");
     359           0 :         ret = EIO;
     360           0 :         goto done;
     361             :     }
     362             : 
     363           0 :     ret = EOK;
     364             : done:
     365           0 :     sss_semanage_close(handle);
     366           0 :     return ret;
     367             : }
     368             : 
     369           0 : int get_seuser(TALLOC_CTX *mem_ctx, const char *login_name,
     370             :                char **_seuser, char **_mls_range)
     371             : {
     372             :     errno_t ret;
     373             :     const char *seuser;
     374             :     const char *mls_range;
     375           0 :     semanage_handle_t *sm_handle = NULL;
     376           0 :     semanage_seuser_t *sm_user = NULL;
     377           0 :     semanage_seuser_key_t *sm_key = NULL;
     378             : 
     379           0 :     sm_handle = sss_semanage_init();
     380           0 :     if (sm_handle == NULL) {
     381           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Cannot create SELinux handle\n");
     382           0 :         ret = EIO;
     383           0 :         goto done;
     384             :     }
     385             : 
     386           0 :     ret = semanage_seuser_key_create(sm_handle, login_name, &sm_key);
     387           0 :     if (ret != EOK) {
     388           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Cannot create key for %s\n", login_name);
     389           0 :         ret = EIO;
     390           0 :         goto done;
     391             :     }
     392             : 
     393           0 :     ret = semanage_seuser_query(sm_handle, sm_key, &sm_user);
     394           0 :     if (ret < 0) {
     395           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Cannot query for %s\n", login_name);
     396           0 :         ret = EIO;
     397           0 :         goto done;
     398             :     }
     399             : 
     400           0 :     seuser = semanage_seuser_get_sename(sm_user);
     401           0 :     if (seuser != NULL) {
     402           0 :         *_seuser = talloc_strdup(mem_ctx, seuser);
     403           0 :         if (*_seuser == NULL) {
     404           0 :             ret = ENOMEM;
     405           0 :             goto done;
     406             :         }
     407           0 :         DEBUG(SSSDBG_OP_FAILURE,
     408             :               "SELinux user for %s: %s\n", login_name, *_seuser);
     409             :     } else {
     410           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Cannot get sename for %s\n", login_name);
     411             :     }
     412             : 
     413           0 :     mls_range = semanage_seuser_get_mlsrange(sm_user);
     414           0 :     if (mls_range != NULL) {
     415           0 :         *_mls_range = talloc_strdup(mem_ctx, mls_range);
     416           0 :         if (*_mls_range == NULL) {
     417           0 :             ret = ENOMEM;
     418           0 :             goto done;
     419             :         }
     420           0 :         DEBUG(SSSDBG_OP_FAILURE,
     421             :               "SELinux range for %s: %s\n", login_name, *_mls_range);
     422             :     } else {
     423           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Cannot get mlsrange for %s\n", login_name);
     424             :     }
     425             : 
     426           0 :     ret = EOK;
     427             : done:
     428           0 :     semanage_seuser_key_free(sm_key);
     429           0 :     semanage_seuser_free(sm_user);
     430           0 :     sss_semanage_close(sm_handle);
     431           0 :     return ret;
     432             : }
     433             : 
     434             : #else /* HAVE_SEMANAGE */
     435             : int set_seuser(const char *login_name, const char *seuser_name,
     436             :                const char *mls)
     437             : {
     438             :     return EOK;
     439             : }
     440             : 
     441             : int del_seuser(const char *login_name)
     442             : {
     443             :     return EOK;
     444             : }
     445             : 
     446             : int get_seuser(TALLOC_CTX *mem_ctx, const char *login_name,
     447             :                char **_seuser, char **_mls_range)
     448             : {
     449             :     return EOK;
     450             : }
     451             : #endif  /* HAVE_SEMANAGE */

Generated by: LCOV version 1.10