LCOV - code coverage report
Current view: top level - tools - sss_useradd.c (source / functions) Hit Total Coverage
Test: .coverage.total Lines: 0 161 0.0 %
Date: 2015-10-19 Functions: 0 1 0.0 %

          Line data    Source code
       1             : /*
       2             :    SSSD
       3             : 
       4             :    sss_useradd
       5             : 
       6             :    Copyright (C) Jakub Hrozek <jhrozek@redhat.com>        2009
       7             :    Copyright (C) Simo Sorce <ssorce@redhat.com>           2009
       8             : 
       9             :    This program is free software; you can redistribute it and/or modify
      10             :    it under the terms of the GNU General Public License as published by
      11             :    the Free Software Foundation; either version 3 of the License, or
      12             :    (at your option) any later version.
      13             : 
      14             :    This program is distributed in the hope that it will be useful,
      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      17             :    GNU General Public License for more details.
      18             : 
      19             :    You should have received a copy of the GNU General Public License
      20             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      21             : */
      22             : 
      23             : #include <stdio.h>
      24             : #include <stdlib.h>
      25             : #include <talloc.h>
      26             : #include <popt.h>
      27             : #include <errno.h>
      28             : #include <unistd.h>
      29             : 
      30             : #include "util/util.h"
      31             : #include "db/sysdb.h"
      32             : #include "tools/tools_util.h"
      33             : #include "tools/sss_sync_ops.h"
      34             : 
      35           0 : int main(int argc, const char **argv)
      36             : {
      37           0 :     uid_t pc_uid = 0;
      38           0 :     const char *pc_gecos = NULL;
      39           0 :     const char *pc_home = NULL;
      40           0 :     char *pc_shell = NULL;
      41           0 :     int pc_debug = SSSDBG_DEFAULT;
      42           0 :     int pc_create_home = 0;
      43           0 :     const char *pc_username = NULL;
      44           0 :     const char *pc_skeldir = NULL;
      45           0 :     const char *pc_selinux_user = NULL;
      46           0 :     struct poptOption long_options[] = {
      47             :         POPT_AUTOHELP
      48           0 :         { "debug", '\0', POPT_ARG_INT | POPT_ARGFLAG_DOC_HIDDEN, &pc_debug, 0, _("The debug level to run with"), NULL },
      49           0 :         { "uid",   'u', POPT_ARG_INT, &pc_uid, 0, _("The UID of the user"), NULL },
      50           0 :         { "gecos", 'c', POPT_ARG_STRING, &pc_gecos, 0, _("The comment string"), NULL },
      51           0 :         { "home",  'h', POPT_ARG_STRING, &pc_home, 0, _("Home directory"), NULL },
      52           0 :         { "shell", 's', POPT_ARG_STRING, &pc_shell, 0, _("Login shell"), NULL },
      53           0 :         { "groups", 'G', POPT_ARG_STRING, NULL, 'G', _("Groups"), NULL },
      54           0 :         { "create-home", 'm', POPT_ARG_NONE, NULL, 'm', _("Create user's directory if it does not exist"), NULL },
      55           0 :         { "no-create-home", 'M', POPT_ARG_NONE, NULL, 'M', _("Never create user's directory, overrides config"), NULL },
      56           0 :         { "skel", 'k', POPT_ARG_STRING, &pc_skeldir, 0, _("Specify an alternative skeleton directory"), NULL },
      57           0 :         { "selinux-user", 'Z', POPT_ARG_STRING, &pc_selinux_user, 0, _("The SELinux user for user's login"), NULL },
      58             :         POPT_TABLEEND
      59             :     };
      60           0 :     poptContext pc = NULL;
      61           0 :     struct tools_ctx *tctx = NULL;
      62           0 :     char *groups = NULL;
      63           0 :     char *badgroup = NULL;
      64             :     int ret;
      65             :     errno_t sret;
      66           0 :     bool in_transaction = false;
      67             : 
      68           0 :     debug_prg_name = argv[0];
      69             : 
      70           0 :     ret = set_locale();
      71           0 :     if (ret != EOK) {
      72           0 :         DEBUG(SSSDBG_CRIT_FAILURE,
      73             :               "set_locale failed (%d): %s\n", ret, strerror(ret));
      74           0 :         ERROR("Error setting the locale\n");
      75           0 :         ret = EXIT_FAILURE;
      76           0 :         goto fini;
      77             :     }
      78             : 
      79             :     /* parse parameters */
      80           0 :     pc = poptGetContext(NULL, argc, argv, long_options, 0);
      81           0 :     poptSetOtherOptionHelp(pc, "USERNAME");
      82           0 :     while ((ret = poptGetNextOpt(pc)) > 0) {
      83           0 :         switch (ret) {
      84             :             case 'G':
      85           0 :                 groups = poptGetOptArg(pc);
      86           0 :                 if (!groups) {
      87           0 :                     BAD_POPT_PARAMS(pc, _("Specify group to add to\n"),
      88             :                                     ret, fini);
      89             :                 }
      90           0 :                 break;
      91             : 
      92             :             case 'm':
      93           0 :                 pc_create_home = DO_CREATE_HOME;
      94           0 :                 break;
      95             : 
      96             :             case 'M':
      97           0 :                 pc_create_home = DO_NOT_CREATE_HOME;
      98           0 :                 break;
      99             :         }
     100             :     }
     101             : 
     102           0 :     DEBUG_CLI_INIT(pc_debug);
     103             : 
     104           0 :     if (ret != -1) {
     105           0 :         BAD_POPT_PARAMS(pc, poptStrerror(ret), ret, fini);
     106             :     }
     107             : 
     108             :     /* username is an argument without --option */
     109           0 :     pc_username = poptGetArg(pc);
     110           0 :     if (pc_username == NULL) {
     111           0 :         BAD_POPT_PARAMS(pc, _("Specify user to add\n"), ret, fini);
     112             :     }
     113             : 
     114           0 :     CHECK_ROOT(ret, debug_prg_name);
     115             : 
     116           0 :     ret = init_sss_tools(&tctx);
     117           0 :     if (ret != EOK) {
     118           0 :         DEBUG(SSSDBG_CRIT_FAILURE,
     119             :               "init_sss_tools failed (%d): %s\n", ret, strerror(ret));
     120           0 :         if (ret == ENOENT) {
     121           0 :             ERROR("Error initializing the tools - no local domain\n");
     122             :         } else {
     123           0 :             ERROR("Error initializing the tools\n");
     124             :         }
     125           0 :         ret = EXIT_FAILURE;
     126           0 :         goto fini;
     127             :     }
     128             : 
     129             :     /* if the domain was not given as part of FQDN, default to local domain */
     130           0 :     ret = parse_name_domain(tctx, pc_username);
     131           0 :     if (ret != EOK) {
     132           0 :         ERROR("Invalid domain specified in FQDN\n");
     133           0 :         ret = EXIT_FAILURE;
     134           0 :         goto fini;
     135             :     }
     136             : 
     137           0 :     if (groups) {
     138           0 :         ret = parse_groups(tctx, groups, &tctx->octx->addgroups);
     139           0 :         if (ret != EOK) {
     140           0 :             DEBUG(SSSDBG_CRIT_FAILURE,
     141             :                   "Cannot parse groups to add the user to\n");
     142           0 :             ERROR("Internal error while parsing parameters\n");
     143           0 :             ret = EXIT_FAILURE;
     144           0 :             goto fini;
     145             :         }
     146             : 
     147           0 :         ret = parse_group_name_domain(tctx, tctx->octx->addgroups);
     148           0 :         if (ret != EOK) {
     149           0 :             DEBUG(SSSDBG_CRIT_FAILURE,
     150             :                   "Cannot parse FQDN groups to add the user to\n");
     151           0 :             ERROR("Groups must be in the same domain as user\n");
     152           0 :             ret = EXIT_FAILURE;
     153           0 :             goto fini;
     154             :         }
     155             : 
     156             :         /* Check group names in the LOCAL domain */
     157           0 :         ret = check_group_names(tctx, tctx->octx->addgroups, &badgroup);
     158           0 :         if (ret != EOK) {
     159           0 :             ERROR("Cannot find group %1$s in local domain\n", badgroup);
     160           0 :             ret = EXIT_FAILURE;
     161           0 :             goto fini;
     162             :         }
     163             :     }
     164             : 
     165           0 :     tctx->octx->uid = pc_uid;
     166             : 
     167             :     /*
     168             :      * Fills in defaults for ops_ctx user did not specify.
     169             :      */
     170           0 :     ret = useradd_defaults(tctx, tctx->confdb, tctx->octx,
     171             :                            pc_gecos, pc_home, pc_shell,
     172             :                            pc_create_home, pc_skeldir);
     173           0 :     if (ret != EOK) {
     174           0 :         ERROR("Cannot set default values\n");
     175           0 :         ret = EXIT_FAILURE;
     176           0 :         goto fini;
     177             :     }
     178             : 
     179             :     /* arguments processed, go on to actual work */
     180           0 :     if (id_in_range(tctx->octx->uid, tctx->octx->domain) != EOK) {
     181           0 :         ERROR("The selected UID is outside the allowed range\n");
     182           0 :         ret = EXIT_FAILURE;
     183           0 :         goto fini;
     184             :     }
     185             : 
     186           0 :     tctx->error = sysdb_transaction_start(tctx->sysdb);
     187           0 :     if (tctx->error != EOK) {
     188           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Failed to start transaction\n");
     189           0 :         goto done;
     190             :     }
     191           0 :     in_transaction = true;
     192             : 
     193             :     /* useradd */
     194           0 :     tctx->error = useradd(tctx, tctx->octx);
     195           0 :     if (tctx->error) {
     196           0 :         goto done;
     197             :     }
     198             : 
     199           0 :     tctx->error = sysdb_transaction_commit(tctx->sysdb);
     200           0 :     if (tctx->error) {
     201           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Failed to commit transaction\n");
     202           0 :         goto done;
     203             :     }
     204           0 :     in_transaction = false;
     205             : 
     206             :     /* Set SELinux login context - must be done after transaction is done
     207             :      * b/c libselinux calls getpwnam */
     208           0 :     ret = set_seuser(tctx->octx->name, pc_selinux_user, NULL);
     209           0 :     if (ret != EOK) {
     210           0 :         ERROR("Cannot set SELinux login context\n");
     211           0 :         ret = EXIT_FAILURE;
     212           0 :         goto fini;
     213             :     }
     214             : 
     215             :     /* Create user's home directory and/or mail spool */
     216           0 :     if (tctx->octx->create_homedir) {
     217             :         /* We need to know the UID of the user, if
     218             :          * sysdb did assign it automatically, do a lookup */
     219           0 :         if (tctx->octx->uid == 0) {
     220           0 :             ret = sysdb_getpwnam_sync(tctx,
     221           0 :                                       tctx->octx->name,
     222           0 :                                       tctx->octx);
     223           0 :             if (ret != EOK) {
     224           0 :                 ERROR("Cannot get info about the user\n");
     225           0 :                 ret = EXIT_FAILURE;
     226           0 :                 goto fini;
     227             :             }
     228             :         }
     229             : 
     230           0 :         ret = create_homedir(tctx->octx->skeldir,
     231           0 :                              tctx->octx->home,
     232           0 :                              tctx->octx->uid,
     233           0 :                              tctx->octx->gid,
     234           0 :                              tctx->octx->umask);
     235           0 :         if (ret == EEXIST) {
     236           0 :             ERROR("User's home directory already exists, not copying "
     237             :                   "data from skeldir\n");
     238           0 :         } else if (ret != EOK) {
     239           0 :             ERROR("Cannot create user's home directory: %1$s\n", strerror(ret));
     240           0 :             ret = EXIT_FAILURE;
     241           0 :             goto fini;
     242             :         }
     243             : 
     244           0 :         ret = create_mail_spool(tctx,
     245           0 :                                 tctx->octx->name,
     246           0 :                                 tctx->octx->maildir,
     247           0 :                                 tctx->octx->uid,
     248           0 :                                 tctx->octx->gid);
     249           0 :         if (ret != EOK) {
     250           0 :             ERROR("Cannot create user's mail spool: %1$s\n", strerror(ret));
     251           0 :             DEBUG(SSSDBG_CRIT_FAILURE,
     252             :                   "Cannot create user's mail spool: [%d][%s].\n",
     253             :                         ret, strerror(ret));
     254           0 :             ret = EXIT_FAILURE;
     255           0 :             goto fini;
     256             :         }
     257             :     }
     258             : 
     259             : done:
     260           0 :     if (in_transaction) {
     261           0 :         sret = sysdb_transaction_cancel(tctx->sysdb);
     262           0 :         if (sret != EOK) {
     263           0 :             DEBUG(SSSDBG_CRIT_FAILURE, "Failed to cancel transaction\n");
     264             :         }
     265             :     }
     266             : 
     267           0 :     if (tctx->error) {
     268           0 :         switch (tctx->error) {
     269             :             case ERANGE:
     270           0 :                 ERROR("Could not allocate ID for the user - domain full?\n");
     271           0 :                 break;
     272             : 
     273             :             case EEXIST:
     274           0 :                 ERROR("A user or group with the same name or ID already exists\n");
     275           0 :                 break;
     276             : 
     277             :             default:
     278           0 :                 DEBUG(SSSDBG_CRIT_FAILURE, "sysdb operation failed (%d)[%s]\n",
     279             :                           tctx->error, strerror(tctx->error));
     280           0 :                 ERROR("Transaction error. Could not add user.\n");
     281           0 :                 break;
     282             :         }
     283           0 :         ret = EXIT_FAILURE;
     284           0 :         goto fini;
     285             :     }
     286             : 
     287           0 :     ret = EXIT_SUCCESS;
     288             : 
     289             : fini:
     290           0 :     poptFreeContext(pc);
     291           0 :     talloc_free(tctx);
     292           0 :     free(groups);
     293           0 :     exit(ret);
     294             : }

Generated by: LCOV version 1.10