LCOV - code coverage report
Current view: top level - util - sss_semanage.c (source / functions) Hit Total Coverage
Test: .coverage.total Lines: 0 237 0.0 %
Date: 2015-10-19 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             :     int ret;
      43           0 :     char * message = NULL;
      44             :     va_list ap;
      45             : 
      46           0 :     switch (semanage_msg_get_level(handle)) {
      47             :         case SEMANAGE_MSG_ERR:
      48           0 :             level = SSSDBG_CRIT_FAILURE;
      49           0 :             break;
      50             :         case SEMANAGE_MSG_WARN:
      51           0 :             level = SSSDBG_MINOR_FAILURE;
      52           0 :             break;
      53             :         case SEMANAGE_MSG_INFO:
      54           0 :             level = SSSDBG_TRACE_FUNC;
      55           0 :             break;
      56             :     }
      57             : 
      58           0 :     va_start(ap, fmt);
      59           0 :     ret = vasprintf(&message, fmt, ap);
      60           0 :     va_end(ap);
      61           0 :     if (ret < 0) {
      62             :         /* ENOMEM */
      63           0 :         return;
      64             :     }
      65             : 
      66           0 :     if (DEBUG_IS_SET(level))
      67           0 :         debug_fn(__FILE__, __LINE__, "libsemanage", level, "%s\n", message);
      68           0 :     free(message);
      69             : }
      70             : 
      71           0 : static void sss_semanage_close(semanage_handle_t *handle)
      72             : {
      73           0 :     if (handle == NULL) {
      74           0 :         return;     /* semanage uses asserts */
      75             :     }
      76             : 
      77           0 :     if (semanage_is_connected(handle)) {
      78           0 :         semanage_disconnect(handle);
      79             :     }
      80           0 :     semanage_handle_destroy(handle);
      81             : }
      82             : 
      83           0 : static semanage_handle_t *sss_semanage_init(void)
      84             : {
      85             :     int ret;
      86           0 :     semanage_handle_t *handle = NULL;
      87             : 
      88           0 :     handle = semanage_handle_create();
      89           0 :     if (!handle) {
      90           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Cannot create SELinux management handle\n");
      91           0 :         return NULL;
      92             :     }
      93             : 
      94           0 :     semanage_msg_set_callback(handle,
      95             :                               sss_semanage_error_callback,
      96             :                               NULL);
      97             : 
      98           0 :     ret = semanage_is_managed(handle);
      99           0 :     if (ret != 1) {
     100           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "SELinux policy not managed\n");
     101           0 :         goto fail;
     102             :     }
     103             : 
     104           0 :     ret = semanage_access_check(handle);
     105           0 :     if (ret < SEMANAGE_CAN_READ) {
     106           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Cannot read SELinux policy store\n");
     107           0 :         goto fail;
     108             :     }
     109             : 
     110           0 :     ret = semanage_connect(handle);
     111           0 :     if (ret != 0) {
     112           0 :         DEBUG(SSSDBG_CRIT_FAILURE,
     113             :               "Cannot estabilish SELinux management connection\n");
     114           0 :         goto fail;
     115             :     }
     116             : 
     117           0 :     return handle;
     118             : fail:
     119           0 :     sss_semanage_close(handle);
     120           0 :     return NULL;
     121             : }
     122             : 
     123           0 : static int sss_semanage_user_add(semanage_handle_t *handle,
     124             :                                  semanage_seuser_key_t *key,
     125             :                                  const char *login_name,
     126             :                                  const char *seuser_name,
     127             :                                  const char *mls)
     128             : {
     129             :     int ret;
     130           0 :     semanage_seuser_t *seuser = NULL;
     131             : 
     132           0 :     ret = semanage_seuser_create(handle, &seuser);
     133           0 :     if (ret != 0) {
     134           0 :         DEBUG(SSSDBG_CRIT_FAILURE,
     135             :               "Cannot create SELinux login mapping for %s\n", login_name);
     136           0 :         ret = EIO;
     137           0 :         goto done;
     138             :     }
     139             : 
     140           0 :     ret = semanage_seuser_set_name(handle, seuser, login_name);
     141           0 :     if (ret != 0) {
     142           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Could not set name for %s\n", login_name);
     143           0 :         ret = EIO;
     144           0 :         goto done;
     145             :     }
     146             : 
     147           0 :     ret = semanage_seuser_set_mlsrange(handle, seuser,
     148             :                                        mls ? mls : DEFAULT_SERANGE);
     149           0 :     if (ret != 0) {
     150           0 :         DEBUG(SSSDBG_CRIT_FAILURE,
     151             :               "Could not set serange for %s\n", login_name);
     152           0 :         ret = EIO;
     153           0 :         goto done;
     154             :     }
     155             : 
     156           0 :     ret = semanage_seuser_set_sename(handle, seuser, seuser_name);
     157           0 :     if (ret != 0) {
     158           0 :         DEBUG(SSSDBG_CRIT_FAILURE,
     159             :               "Could not set SELinux user for %s\n", login_name);
     160           0 :         ret = EIO;
     161           0 :         goto done;
     162             :     }
     163             : 
     164           0 :     ret = semanage_seuser_modify_local(handle, key, seuser);
     165           0 :     if (ret != 0) {
     166           0 :         DEBUG(SSSDBG_CRIT_FAILURE,
     167             :               "Could not add login mapping for %s\n", login_name);
     168           0 :         ret = EIO;
     169           0 :         goto done;
     170             :     }
     171             : 
     172           0 :     ret = EOK;
     173             : done:
     174           0 :     semanage_seuser_free(seuser);
     175           0 :     return ret;
     176             : }
     177             : 
     178           0 : static int sss_semanage_user_mod(semanage_handle_t *handle,
     179             :                                  semanage_seuser_key_t *key,
     180             :                                  const char *login_name,
     181             :                                  const char *seuser_name,
     182             :                                  const char *mls)
     183             : {
     184             :     int ret;
     185           0 :     semanage_seuser_t *seuser = NULL;
     186             : 
     187           0 :     semanage_seuser_query(handle, key, &seuser);
     188           0 :     if (seuser == NULL) {
     189           0 :         DEBUG(SSSDBG_CRIT_FAILURE,
     190             :               "Could not query seuser for %s\n", login_name);
     191           0 :         ret = EIO;
     192           0 :         goto done;
     193             :     }
     194             : 
     195           0 :     ret = semanage_seuser_set_mlsrange(handle, seuser,
     196             :                                        mls ? mls : DEFAULT_SERANGE);
     197           0 :     if (ret != 0) {
     198           0 :         DEBUG(SSSDBG_CRIT_FAILURE,
     199             :               "Could not set serange for %s\n", login_name);
     200           0 :         ret = EIO;
     201           0 :         goto done;
     202             :     }
     203             : 
     204           0 :     ret = semanage_seuser_set_sename(handle, seuser, seuser_name);
     205           0 :     if (ret != 0) {
     206           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Could not set sename for %s\n", login_name);
     207           0 :         ret = EIO;
     208           0 :         goto done;
     209             :     }
     210             : 
     211           0 :     ret = semanage_seuser_modify_local(handle, key, seuser);
     212           0 :     if (ret != 0) {
     213           0 :         DEBUG(SSSDBG_CRIT_FAILURE,
     214             :               ("Could not modify login mapping for %s\n"), login_name);
     215           0 :         ret = EIO;
     216           0 :         goto done;
     217             :     }
     218             : 
     219           0 :     ret = EOK;
     220             : done:
     221           0 :     semanage_seuser_free(seuser);
     222           0 :     return ret;
     223             : }
     224             : 
     225           0 : int set_seuser(const char *login_name, const char *seuser_name,
     226             :                const char *mls)
     227             : {
     228           0 :     semanage_handle_t *handle = NULL;
     229           0 :     semanage_seuser_key_t *key = NULL;
     230             :     int ret;
     231           0 :     int seuser_exists = 0;
     232             : 
     233           0 :     if (seuser_name == NULL) {
     234             :         /* don't care, just let system pick the defaults */
     235           0 :         return EOK;
     236             :     }
     237             : 
     238           0 :     handle = sss_semanage_init();
     239           0 :     if (!handle) {
     240           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Cannot init SELinux management\n");
     241           0 :         ret = EIO;
     242           0 :         goto done;
     243             :     }
     244             : 
     245           0 :     ret = semanage_begin_transaction(handle);
     246           0 :     if (ret != 0) {
     247           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Cannot begin SELinux transaction\n");
     248           0 :         ret = EIO;
     249           0 :         goto done;
     250             :     }
     251             : 
     252           0 :     ret = semanage_seuser_key_create(handle, login_name, &key);
     253           0 :     if (ret != 0) {
     254           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Cannot create SELinux user key\n");
     255           0 :         ret = EIO;
     256           0 :         goto done;
     257             :     }
     258             : 
     259           0 :     ret = semanage_seuser_exists(handle, key, &seuser_exists);
     260           0 :     if (ret < 0) {
     261           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Cannot verify the SELinux user\n");
     262           0 :         ret = EIO;
     263           0 :         goto done;
     264             :     }
     265             : 
     266           0 :     if (seuser_exists) {
     267           0 :         ret = sss_semanage_user_mod(handle, key, login_name, seuser_name,
     268             :                                     mls);
     269           0 :         if (ret != 0) {
     270           0 :             DEBUG(SSSDBG_CRIT_FAILURE, "Cannot modify SELinux user mapping\n");
     271           0 :             ret = EIO;
     272           0 :             goto done;
     273             :         }
     274             :     } else {
     275           0 :         ret = sss_semanage_user_add(handle, key, login_name, seuser_name,
     276             :                                     mls);
     277           0 :         if (ret != 0) {
     278           0 :             DEBUG(SSSDBG_CRIT_FAILURE, "Cannot add SELinux user mapping\n");
     279           0 :             ret = EIO;
     280           0 :             goto done;
     281             :         }
     282             :     }
     283             : 
     284           0 :     ret = semanage_commit(handle);
     285           0 :     if (ret < 0) {
     286           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Cannot commit SELinux transaction\n");
     287           0 :         ret = EIO;
     288           0 :         goto done;
     289             :     }
     290             : 
     291           0 :     ret = EOK;
     292             : done:
     293           0 :     semanage_seuser_key_free(key);
     294           0 :     sss_semanage_close(handle);
     295           0 :     return ret;
     296             : }
     297             : 
     298           0 : int del_seuser(const char *login_name)
     299             : {
     300           0 :     semanage_handle_t *handle = NULL;
     301           0 :     semanage_seuser_key_t *key = NULL;
     302             :     int ret;
     303           0 :     int exists = 0;
     304             : 
     305           0 :     handle = sss_semanage_init();
     306           0 :     if (!handle) {
     307           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Cannot init SELinux management\n");
     308           0 :         ret = EIO;
     309           0 :         goto done;
     310             :     }
     311             : 
     312           0 :     ret = semanage_begin_transaction(handle);
     313           0 :     if (ret != 0) {
     314           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Cannot begin SELinux transaction\n");
     315           0 :         ret = EIO;
     316           0 :         goto done;
     317             :     }
     318             : 
     319           0 :     ret = semanage_seuser_key_create(handle, login_name, &key);
     320           0 :     if (ret != 0) {
     321           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Cannot create SELinux user key\n");
     322           0 :         ret = EIO;
     323           0 :         goto done;
     324             :     }
     325             : 
     326           0 :     ret = semanage_seuser_exists(handle, key, &exists);
     327           0 :     if (ret < 0) {
     328           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Cannot verify the SELinux user\n");
     329           0 :         ret = EIO;
     330           0 :         goto done;
     331             :     }
     332             : 
     333           0 :     if (!exists) {
     334           0 :         DEBUG(SSSDBG_FUNC_DATA,
     335             :               "Login mapping for %s is not defined, OK if default mapping "
     336             :                   "was used\n", login_name);
     337           0 :         ret = EOK;  /* probably default mapping */
     338           0 :         goto done;
     339             :     }
     340             : 
     341           0 :     ret = semanage_seuser_exists_local(handle, key, &exists);
     342           0 :     if (ret < 0) {
     343           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Cannot verify the SELinux user\n");
     344           0 :         ret = EIO;
     345           0 :         goto done;
     346             :     }
     347             : 
     348           0 :     if (!exists) {
     349           0 :         DEBUG(SSSDBG_CRIT_FAILURE,
     350             :               "Login mapping for %s is defined in policy, cannot be deleted\n",
     351             :               login_name);
     352           0 :         ret = ENOENT;
     353           0 :         goto done;
     354             :     }
     355             : 
     356           0 :     ret = semanage_seuser_del_local(handle, key);
     357           0 :     if (ret != 0) {
     358           0 :         DEBUG(SSSDBG_CRIT_FAILURE,
     359             :               "Could not delete login mapping for %s\n", login_name);
     360           0 :         ret = EIO;
     361           0 :         goto done;
     362             :     }
     363             : 
     364           0 :     ret = semanage_commit(handle);
     365           0 :     if (ret < 0) {
     366           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Cannot commit SELinux transaction\n");
     367           0 :         ret = EIO;
     368           0 :         goto done;
     369             :     }
     370             : 
     371           0 :     ret = EOK;
     372             : done:
     373           0 :     sss_semanage_close(handle);
     374           0 :     return ret;
     375             : }
     376             : 
     377           0 : int get_seuser(TALLOC_CTX *mem_ctx, const char *login_name,
     378             :                char **_seuser, char **_mls_range)
     379             : {
     380             :     errno_t ret;
     381             :     const char *seuser;
     382             :     const char *mls_range;
     383           0 :     semanage_handle_t *sm_handle = NULL;
     384           0 :     semanage_seuser_t *sm_user = NULL;
     385           0 :     semanage_seuser_key_t *sm_key = NULL;
     386             : 
     387           0 :     sm_handle = sss_semanage_init();
     388           0 :     if (sm_handle == NULL) {
     389           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Cannot create SELinux handle\n");
     390           0 :         ret = EIO;
     391           0 :         goto done;
     392             :     }
     393             : 
     394           0 :     ret = semanage_seuser_key_create(sm_handle, login_name, &sm_key);
     395           0 :     if (ret != EOK) {
     396           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Cannot create key for %s\n", login_name);
     397           0 :         ret = EIO;
     398           0 :         goto done;
     399             :     }
     400             : 
     401           0 :     ret = semanage_seuser_query(sm_handle, sm_key, &sm_user);
     402           0 :     if (ret < 0) {
     403           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Cannot query for %s\n", login_name);
     404           0 :         ret = EIO;
     405           0 :         goto done;
     406             :     }
     407             : 
     408           0 :     seuser = semanage_seuser_get_sename(sm_user);
     409           0 :     if (seuser != NULL) {
     410           0 :         *_seuser = talloc_strdup(mem_ctx, seuser);
     411           0 :         if (*_seuser == NULL) {
     412           0 :             ret = ENOMEM;
     413           0 :             goto done;
     414             :         }
     415           0 :         DEBUG(SSSDBG_OP_FAILURE,
     416             :               "SELinux user for %s: %s\n", login_name, *_seuser);
     417             :     } else {
     418           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Cannot get sename for %s\n", login_name);
     419             :     }
     420             : 
     421           0 :     mls_range = semanage_seuser_get_mlsrange(sm_user);
     422           0 :     if (mls_range != NULL) {
     423           0 :         *_mls_range = talloc_strdup(mem_ctx, mls_range);
     424           0 :         if (*_mls_range == NULL) {
     425           0 :             ret = ENOMEM;
     426           0 :             goto done;
     427             :         }
     428           0 :         DEBUG(SSSDBG_OP_FAILURE,
     429             :               "SELinux range for %s: %s\n", login_name, *_mls_range);
     430             :     } else {
     431           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Cannot get mlsrange for %s\n", login_name);
     432             :     }
     433             : 
     434           0 :     ret = EOK;
     435             : done:
     436           0 :     semanage_seuser_key_free(sm_key);
     437           0 :     semanage_seuser_free(sm_user);
     438           0 :     sss_semanage_close(sm_handle);
     439           0 :     return ret;
     440             : }
     441             : 
     442             : #else /* HAVE_SEMANAGE */
     443             : int set_seuser(const char *login_name, const char *seuser_name,
     444             :                const char *mls)
     445             : {
     446             :     return EOK;
     447             : }
     448             : 
     449             : int del_seuser(const char *login_name)
     450             : {
     451             :     return EOK;
     452             : }
     453             : 
     454             : int get_seuser(TALLOC_CTX *mem_ctx, const char *login_name,
     455             :                char **_seuser, char **_mls_range)
     456             : {
     457             :     return EOK;
     458             : }
     459             : #endif  /* HAVE_SEMANAGE */

Generated by: LCOV version 1.10