LCOV - code coverage report
Current view: top level - tools - selinux.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 9 131 6.9 %
Date: 2012-11-29 Functions: 2 8 25.0 %
Branches: 3 364 0.8 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :    SSSD
       3                 :            : 
       4                 :            :    selinux.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                 :            : 
      26                 :            : #ifdef HAVE_SELINUX
      27                 :            : #include <selinux/selinux.h>
      28                 :            : #endif
      29                 :            : 
      30                 :            : #ifdef HAVE_SEMANAGE
      31                 :            : #include <semanage/semanage.h>
      32                 :            : #endif
      33                 :            : 
      34                 :            : #include "util/util.h"
      35                 :            : 
      36                 :            : #ifndef DEFAULT_SERANGE
      37                 :            : #define DEFAULT_SERANGE "s0"
      38                 :            : #endif
      39                 :            : 
      40                 :            : #ifdef HAVE_SELINUX
      41                 :            : /*
      42                 :            :  * selinux_file_context - Set the security context before any file or
      43                 :            :  *                        directory creation.
      44                 :            :  *
      45                 :            :  *  selinux_file_context () should be called before any creation of file,
      46                 :            :  *  symlink, directory, ...
      47                 :            :  *
      48                 :            :  *  Callers may have to Reset SELinux to create files with default
      49                 :            :  *  contexts:
      50                 :            :  *      reset_selinux_file_context();
      51                 :            :  */
      52                 :          6 : int selinux_file_context(const char *dst_name)
      53                 :            : {
      54                 :          6 :     security_context_t scontext = NULL;
      55                 :            : 
      56         [ +  - ]:          6 :     if (is_selinux_enabled() == 1) {
      57                 :            :         /* Get the default security context for this file */
      58         [ +  - ]:          6 :         if (matchpathcon(dst_name, 0, &scontext) < 0) {
      59         [ -  + ]:          6 :             if (security_getenforce () != 0) {
      60                 :            :                 return 1;
      61                 :            :             }
      62                 :            :         }
      63                 :            :         /* Set the security context for the next created file */
      64         [ #  # ]:          0 :         if (setfscreatecon(scontext) < 0) {
      65         [ #  # ]:          0 :             if (security_getenforce() != 0) {
      66                 :            :                 return 1;
      67                 :            :             }
      68                 :            :         }
      69                 :          6 :         freecon(scontext);
      70                 :            :     }
      71                 :            : 
      72                 :            :     return 0;
      73                 :            : }
      74                 :            : 
      75                 :          4 : int reset_selinux_file_context(void)
      76                 :            : {
      77                 :          4 :     setfscreatecon(NULL);
      78                 :          4 :     return EOK;
      79                 :            : }
      80                 :            : 
      81                 :            : #else   /* HAVE_SELINUX */
      82                 :            : int selinux_file_context(const char *dst_name)
      83                 :            : {
      84                 :            :     return EOK;
      85                 :            : }
      86                 :            : 
      87                 :            : int reset_selinux_file_context(void)
      88                 :            : {
      89                 :            :     return EOK;
      90                 :            : }
      91                 :            : #endif  /* HAVE_SELINUX */
      92                 :            : 
      93                 :            : #ifdef HAVE_SEMANAGE
      94                 :            : /* turn libselinux messages into SSSD DEBUG() calls */
      95                 :          0 : static void sss_semanage_error_callback(void *varg,
      96                 :            :                                         semanage_handle_t *handle,
      97                 :            :                                         const char *fmt, ...)
      98                 :            : {
      99                 :          0 :     int level = -1;
     100                 :            :     int ret;
     101                 :          0 :     char * message = NULL;
     102                 :            :     va_list ap;
     103                 :            : 
     104         [ #  # ]:          0 :     switch (semanage_msg_get_level(handle)) {
     105                 :            :         case SEMANAGE_MSG_ERR:
     106                 :            :             level = 1;
     107                 :            :             break;
     108                 :            :         case SEMANAGE_MSG_WARN:
     109                 :            :             level = 4;
     110                 :            :             break;
     111                 :            :         case SEMANAGE_MSG_INFO:
     112                 :            :             level = 6;
     113                 :            :             break;
     114                 :            :     }
     115                 :            : 
     116                 :          0 :     va_start(ap, fmt);
     117                 :          0 :     ret = vasprintf(&message, fmt, ap);
     118                 :          0 :     va_end(ap);
     119         [ #  # ]:          0 :     if (ret < 0) {
     120                 :            :         /* ENOMEM */
     121                 :          0 :         return;
     122                 :            :     }
     123                 :            : 
     124 [ #  # ][ #  # ]:          0 :     DEBUG_MSG(level, "libsemanage", message);
         [ #  # ][ #  # ]
                 [ #  # ]
     125                 :          0 :     free(message);
     126                 :            : }
     127                 :            : 
     128                 :          0 : static semanage_handle_t *sss_semanage_init(void)
     129                 :            : {
     130                 :            :     int ret;
     131                 :          0 :     semanage_handle_t *handle = NULL;
     132                 :            : 
     133                 :          0 :     handle = semanage_handle_create();
     134         [ #  # ]:          0 :     if (!handle) {
     135 [ #  # ][ #  # ]:          0 :         DEBUG(1, ("Cannot create SELinux management handle\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
     136                 :            :         return NULL;
     137                 :            :     }
     138                 :            : 
     139                 :          0 :     semanage_msg_set_callback(handle,
     140                 :            :                               sss_semanage_error_callback,
     141                 :            :                               NULL);
     142                 :            : 
     143                 :          0 :     ret = semanage_is_managed(handle);
     144         [ #  # ]:          0 :     if (ret != 1) {
     145 [ #  # ][ #  # ]:          0 :         DEBUG(1, ("SELinux policy not managed\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
     146                 :            :         goto fail;
     147                 :            :     }
     148                 :            : 
     149                 :          0 :     ret = semanage_access_check(handle);
     150         [ #  # ]:          0 :     if (ret < SEMANAGE_CAN_READ) {
     151 [ #  # ][ #  # ]:          0 :         DEBUG(1, ("Cannot read SELinux policy store\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
     152                 :            :         goto fail;
     153                 :            :     }
     154                 :            : 
     155                 :          0 :     ret = semanage_connect(handle);
     156         [ #  # ]:          0 :     if (ret != 0) {
     157 [ #  # ][ #  # ]:          0 :         DEBUG(1, ("Cannot estabilish SELinux management connection\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
     158                 :            :         goto fail;
     159                 :            :     }
     160                 :            : 
     161                 :          0 :     ret = semanage_begin_transaction(handle);
     162         [ #  # ]:          0 :     if (ret != 0) {
     163 [ #  # ][ #  # ]:          0 :         DEBUG(1, ("Cannot begin SELinux transaction\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
     164                 :            :         goto fail;
     165                 :            :     }
     166                 :            : 
     167                 :            :     return handle;
     168                 :            : fail:
     169                 :          0 :     semanage_handle_destroy(handle);
     170                 :          0 :     return NULL;
     171                 :            : }
     172                 :            : 
     173                 :          0 : static int sss_semanage_user_add(semanage_handle_t *handle,
     174                 :            :                                  semanage_seuser_key_t *key,
     175                 :            :                                  const char *login_name,
     176                 :            :                                  const char *seuser_name)
     177                 :            : {
     178                 :            :     int ret;
     179                 :          0 :     semanage_seuser_t *seuser = NULL;
     180                 :            : 
     181                 :          0 :     ret = semanage_seuser_create(handle, &seuser);
     182         [ #  # ]:          0 :     if (ret != 0) {
     183 [ #  # ][ #  # ]:          0 :         DEBUG(1, ("Cannot create SELinux login mapping for %s\n", login_name));
         [ #  # ][ #  # ]
                 [ #  # ]
     184                 :            :         ret = EIO;
     185                 :            :         goto done;
     186                 :            :     }
     187                 :            : 
     188                 :          0 :     ret = semanage_seuser_set_name(handle, seuser, login_name);
     189         [ #  # ]:          0 :     if (ret != 0) {
     190 [ #  # ][ #  # ]:          0 :         DEBUG(1, ("Could not set name for %s\n", login_name));
         [ #  # ][ #  # ]
                 [ #  # ]
     191                 :            :         ret = EIO;
     192                 :            :         goto done;
     193                 :            :     }
     194                 :            : 
     195                 :          0 :     ret = semanage_seuser_set_mlsrange(handle, seuser, DEFAULT_SERANGE);
     196         [ #  # ]:          0 :     if (ret != 0) {
     197 [ #  # ][ #  # ]:          0 :         DEBUG(1, ("Could not set serange for %s\n", login_name));
         [ #  # ][ #  # ]
                 [ #  # ]
     198                 :            :         ret = EIO;
     199                 :            :         goto done;
     200                 :            :     }
     201                 :            : 
     202                 :          0 :     ret = semanage_seuser_set_sename(handle, seuser, seuser_name);
     203         [ #  # ]:          0 :     if (ret != 0) {
     204 [ #  # ][ #  # ]:          0 :         DEBUG(1, ("Could not set SELinux user for %s\n", login_name));
         [ #  # ][ #  # ]
                 [ #  # ]
     205                 :            :         ret = EIO;
     206                 :            :         goto done;
     207                 :            :     }
     208                 :            : 
     209                 :          0 :     ret = semanage_seuser_modify_local(handle, key, seuser);
     210         [ #  # ]:          0 :     if (ret != 0) {
     211 [ #  # ][ #  # ]:          0 :         DEBUG(1, ("Could not add login mapping for %s\n", login_name));
         [ #  # ][ #  # ]
                 [ #  # ]
     212                 :            :         ret = EIO;
     213                 :            :         goto done;
     214                 :            :     }
     215                 :            : 
     216                 :            :     ret = EOK;
     217                 :            : done:
     218                 :          0 :     semanage_seuser_free(seuser);
     219                 :          0 :     return ret;
     220                 :            : }
     221                 :            : 
     222                 :          0 : static int sss_semanage_user_mod(semanage_handle_t *handle,
     223                 :            :                                  semanage_seuser_key_t *key,
     224                 :            :                                  const char *login_name,
     225                 :            :                                  const char *seuser_name)
     226                 :            : {
     227                 :            :     int ret;
     228                 :          0 :     semanage_seuser_t *seuser = NULL;
     229                 :            : 
     230                 :          0 :     semanage_seuser_query(handle, key, &seuser);
     231         [ #  # ]:          0 :     if (seuser == NULL) {
     232 [ #  # ][ #  # ]:          0 :         DEBUG(1, ("Could not query seuser for %s\n", login_name));
         [ #  # ][ #  # ]
                 [ #  # ]
     233                 :            :         ret = EIO;
     234                 :            :         goto done;
     235                 :            :     }
     236                 :            : 
     237                 :          0 :     ret = semanage_seuser_set_mlsrange(handle, seuser, DEFAULT_SERANGE);
     238         [ #  # ]:          0 :     if (ret != 0) {
     239 [ #  # ][ #  # ]:          0 :         DEBUG(1, ("Could not set serange for %s\n", login_name));
         [ #  # ][ #  # ]
                 [ #  # ]
     240                 :            :         ret = EIO;
     241                 :            :         goto done;
     242                 :            :     }
     243                 :            : 
     244                 :          0 :     ret = semanage_seuser_set_sename(handle, seuser, seuser_name);
     245         [ #  # ]:          0 :     if (ret != 0) {
     246 [ #  # ][ #  # ]:          0 :         DEBUG(1, ("Could not set sename for %s\n", login_name));
         [ #  # ][ #  # ]
                 [ #  # ]
     247                 :            :         ret = EIO;
     248                 :            :         goto done;
     249                 :            :     }
     250                 :            : 
     251                 :          0 :     ret = semanage_seuser_modify_local(handle, key, seuser);
     252         [ #  # ]:          0 :     if (ret != 0) {
     253 [ #  # ][ #  # ]:          0 :         DEBUG(1, (("Could not modify login mapping for %s\n"), login_name));
         [ #  # ][ #  # ]
                 [ #  # ]
     254                 :            :         ret = EIO;
     255                 :            :         goto done;
     256                 :            :     }
     257                 :            : 
     258                 :            :     ret = EOK;
     259                 :            : done:
     260                 :          0 :     semanage_seuser_free(seuser);
     261                 :          0 :     return ret;
     262                 :            : }
     263                 :            : 
     264                 :          0 : int set_seuser(const char *login_name, const char *seuser_name)
     265                 :            : {
     266                 :          0 :     semanage_handle_t *handle = NULL;
     267                 :          0 :     semanage_seuser_key_t *key = NULL;
     268                 :            :     int ret;
     269                 :          0 :     int seuser_exists = 0;
     270                 :            : 
     271         [ #  # ]:          0 :     if (seuser_name == NULL) {
     272                 :            :         /* don't care, just let system pick the defaults */
     273                 :            :         return EOK;
     274                 :            :     }
     275                 :            : 
     276                 :          0 :     handle = sss_semanage_init();
     277         [ #  # ]:          0 :     if (!handle) {
     278 [ #  # ][ #  # ]:          0 :         DEBUG(1, ("Cannot init SELinux management\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
     279                 :            :         ret = EIO;
     280                 :            :         goto done;
     281                 :            :     }
     282                 :            : 
     283                 :          0 :     ret = semanage_seuser_key_create(handle, login_name, &key);
     284         [ #  # ]:          0 :     if (ret != 0) {
     285 [ #  # ][ #  # ]:          0 :         DEBUG(1, ("Cannot create SELinux user key\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
     286                 :            :         ret = EIO;
     287                 :            :         goto done;
     288                 :            :     }
     289                 :            : 
     290                 :          0 :     ret = semanage_seuser_exists(handle, key, &seuser_exists);
     291         [ #  # ]:          0 :     if (ret < 0) {
     292 [ #  # ][ #  # ]:          0 :         DEBUG(1, ("Cannot verify the SELinux user\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
     293                 :            :         ret = EIO;
     294                 :            :         goto done;
     295                 :            :     }
     296                 :            : 
     297         [ #  # ]:          0 :     if (seuser_exists) {
     298                 :          0 :         ret = sss_semanage_user_mod(handle, key, login_name, seuser_name);
     299         [ #  # ]:          0 :         if (ret != 0) {
     300 [ #  # ][ #  # ]:          0 :             DEBUG(1, ("Cannot modify SELinux user mapping\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
     301                 :            :             ret = EIO;
     302                 :            :             goto done;
     303                 :            :         }
     304                 :            :     } else {
     305                 :          0 :         ret = sss_semanage_user_add(handle, key, login_name, seuser_name);
     306         [ #  # ]:          0 :         if (ret != 0) {
     307 [ #  # ][ #  # ]:          0 :             DEBUG(1, ("Cannot add SELinux user mapping\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
     308                 :            :             ret = EIO;
     309                 :            :             goto done;
     310                 :            :         }
     311                 :            :     }
     312                 :            : 
     313                 :          0 :     ret = semanage_commit(handle);
     314         [ #  # ]:          0 :     if (ret < 0) {
     315 [ #  # ][ #  # ]:          0 :         DEBUG(1, ("Cannot commit SELinux transaction\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
     316                 :            :         ret = EIO;
     317                 :            :         goto done;
     318                 :            :     }
     319                 :            : 
     320                 :            :     ret = EOK;
     321                 :            : done:
     322                 :          0 :     semanage_seuser_key_free(key);
     323                 :          0 :     semanage_handle_destroy(handle);
     324                 :            :     return ret;
     325                 :            : }
     326                 :            : 
     327                 :          0 : int del_seuser(const char *login_name)
     328                 :            : {
     329                 :          0 :     semanage_handle_t *handle = NULL;
     330                 :          0 :     semanage_seuser_key_t *key = NULL;
     331                 :            :     int ret;
     332                 :          0 :     int exists = 0;
     333                 :            : 
     334                 :          0 :     handle = sss_semanage_init();
     335         [ #  # ]:          0 :     if (!handle) {
     336 [ #  # ][ #  # ]:          0 :         DEBUG(1, ("Cannot init SELinux management\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
     337                 :            :         ret = EIO;
     338                 :            :         goto done;
     339                 :            :     }
     340                 :            : 
     341                 :          0 :     ret = semanage_seuser_key_create(handle, login_name, &key);
     342         [ #  # ]:          0 :     if (ret != 0) {
     343 [ #  # ][ #  # ]:          0 :         DEBUG(1, ("Cannot create SELinux user key\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
     344                 :            :         ret = EIO;
     345                 :            :         goto done;
     346                 :            :     }
     347                 :            : 
     348                 :          0 :     ret = semanage_seuser_exists(handle, key, &exists);
     349         [ #  # ]:          0 :     if (ret < 0) {
     350 [ #  # ][ #  # ]:          0 :         DEBUG(1, ("Cannot verify the SELinux user\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
     351                 :            :         ret = EIO;
     352                 :            :         goto done;
     353                 :            :     }
     354                 :            : 
     355         [ #  # ]:          0 :     if (!exists) {
     356 [ #  # ][ #  # ]:          0 :         DEBUG(5, ("Login mapping for %s is not defined, OK if default mapping "
         [ #  # ][ #  # ]
                 [ #  # ]
     357                 :            :                   "was used\n", login_name));
     358                 :            :         ret = EOK;  /* probably default mapping */
     359                 :            :         goto done;
     360                 :            :     }
     361                 :            : 
     362                 :          0 :     ret = semanage_seuser_exists_local(handle, key, &exists);
     363         [ #  # ]:          0 :     if (ret < 0) {
     364 [ #  # ][ #  # ]:          0 :         DEBUG(1, ("Cannot verify the SELinux user\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
     365                 :            :         ret = EIO;
     366                 :            :         goto done;
     367                 :            :     }
     368                 :            : 
     369         [ #  # ]:          0 :     if (!exists) {
     370 [ #  # ][ #  # ]:          0 :         DEBUG(1, ("Login mapping for %s is defined in policy, "
         [ #  # ][ #  # ]
                 [ #  # ]
     371                 :            :                   "cannot be deleted", login_name));
     372                 :            :         ret = ENOENT;
     373                 :            :         goto done;
     374                 :            :     }
     375                 :            : 
     376                 :          0 :     ret = semanage_seuser_del_local(handle, key);
     377         [ #  # ]:          0 :     if (ret != 0) {
     378 [ #  # ][ #  # ]:          0 :         DEBUG(1, ("Could not delete login mapping for %s", login_name));
         [ #  # ][ #  # ]
                 [ #  # ]
     379                 :            :         ret = EIO;
     380                 :            :         goto done;
     381                 :            :     }
     382                 :            : 
     383                 :          0 :     ret = semanage_commit(handle);
     384         [ #  # ]:          0 :     if (ret < 0) {
     385 [ #  # ][ #  # ]:          0 :         DEBUG(1, ("Cannot commit SELinux transaction\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
     386                 :            :         ret = EIO;
     387                 :            :         goto done;
     388                 :            :     }
     389                 :            : 
     390                 :            :     ret = EOK;
     391                 :            : done:
     392                 :          0 :     semanage_handle_destroy(handle);
     393                 :          0 :     return ret;
     394                 :            : }
     395                 :            : 
     396                 :            : #else /* HAVE_SEMANAGE */
     397                 :            : int set_seuser(const char *login_name, const char *seuser_name)
     398                 :            : {
     399                 :            :     return EOK;
     400                 :            : }
     401                 :            : 
     402                 :            : int del_seuser(const char *login_name)
     403                 :            : {
     404                 :            :     return EOK;
     405                 :            : }
     406                 :            : #endif  /* HAVE_SEMANAGE */

Generated by: LCOV version 1.9