Line data Source code
1 : /*
2 : SSSD
3 :
4 : sss_groupadd
5 :
6 : Copyright (C) Jakub Hrozek <jhrozek@redhat.com> 2009
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 <stdio.h>
23 : #include <stdlib.h>
24 : #include <talloc.h>
25 : #include <popt.h>
26 : #include <errno.h>
27 : #include <unistd.h>
28 :
29 : #include "util/util.h"
30 : #include "db/sysdb.h"
31 : #include "tools/tools_util.h"
32 : #include "tools/sss_sync_ops.h"
33 :
34 0 : int main(int argc, const char **argv)
35 : {
36 0 : gid_t pc_gid = 0;
37 0 : int pc_debug = SSSDBG_DEFAULT;
38 0 : struct poptOption long_options[] = {
39 : POPT_AUTOHELP
40 : { "debug",'\0', POPT_ARG_INT | POPT_ARGFLAG_DOC_HIDDEN, &pc_debug,
41 0 : 0, _("The debug level to run with"), NULL },
42 : { "gid", 'g', POPT_ARG_INT, &pc_gid,
43 0 : 0, _("The GID of the group"), NULL },
44 : POPT_TABLEEND
45 : };
46 0 : poptContext pc = NULL;
47 0 : struct tools_ctx *tctx = NULL;
48 0 : int ret = EXIT_SUCCESS;
49 : errno_t sret;
50 0 : const char *pc_groupname = NULL;
51 0 : bool in_transaction = false;
52 :
53 0 : debug_prg_name = argv[0];
54 :
55 0 : ret = set_locale();
56 0 : if (ret != EOK) {
57 0 : DEBUG(SSSDBG_CRIT_FAILURE,
58 : "set_locale failed (%d): %s\n", ret, strerror(ret));
59 0 : ERROR("Error setting the locale\n");
60 0 : ret = EXIT_FAILURE;
61 0 : goto fini;
62 : }
63 :
64 : /* parse params */
65 0 : pc = poptGetContext(NULL, argc, argv, long_options, 0);
66 0 : poptSetOtherOptionHelp(pc, "GROUPNAME");
67 0 : if ((ret = poptGetNextOpt(pc)) < -1) {
68 0 : BAD_POPT_PARAMS(pc, poptStrerror(ret), ret, fini);
69 : }
70 :
71 0 : DEBUG_CLI_INIT(pc_debug);
72 :
73 : /* groupname is an argument, not option */
74 0 : pc_groupname = poptGetArg(pc);
75 0 : if (pc_groupname == NULL) {
76 0 : BAD_POPT_PARAMS(pc, _("Specify group to add\n"), ret, fini);
77 : }
78 :
79 0 : CHECK_ROOT(ret, debug_prg_name);
80 :
81 0 : ret = init_sss_tools(&tctx);
82 0 : if (ret != EOK) {
83 0 : DEBUG(SSSDBG_CRIT_FAILURE,
84 : "init_sss_tools failed (%d): %s\n", ret, strerror(ret));
85 0 : if (ret == ENOENT) {
86 0 : ERROR("Error initializing the tools - no local domain\n");
87 : } else {
88 0 : ERROR("Error initializing the tools\n");
89 : }
90 0 : ret = EXIT_FAILURE;
91 0 : goto fini;
92 : }
93 :
94 : /* if the domain was not given as part of FQDN, default to local domain */
95 0 : ret = parse_name_domain(tctx, pc_groupname);
96 0 : if (ret != EOK) {
97 0 : ERROR("Invalid domain specified in FQDN\n");
98 0 : ret = EXIT_FAILURE;
99 0 : goto fini;
100 : }
101 :
102 0 : tctx->octx->gid = pc_gid;
103 :
104 : /* arguments processed, go on to actual work */
105 0 : if (id_in_range(tctx->octx->gid, tctx->octx->domain) != EOK) {
106 0 : ERROR("The selected GID is outside the allowed range\n");
107 0 : ret = EXIT_FAILURE;
108 0 : goto fini;
109 : }
110 :
111 0 : tctx->error = sysdb_transaction_start(tctx->sysdb);
112 0 : if (tctx->error != EOK) {
113 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Failed to start transaction\n");
114 0 : goto done;
115 : }
116 0 : in_transaction = true;
117 :
118 : /* groupadd */
119 0 : tctx->error = groupadd(tctx->octx);
120 0 : if (tctx->error) {
121 0 : goto done;
122 : }
123 :
124 0 : tctx->error = sysdb_transaction_commit(tctx->sysdb);
125 0 : if (tctx->error != EOK) {
126 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Failed to commit transaction\n");
127 0 : goto done;
128 : }
129 0 : in_transaction = false;
130 :
131 : done:
132 0 : if (in_transaction) {
133 0 : sret = sysdb_transaction_cancel(tctx->sysdb);
134 0 : if (sret != EOK) {
135 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Failed to cancel transaction\n");
136 : }
137 : }
138 :
139 0 : if (tctx->error) {
140 0 : ret = tctx->error;
141 0 : switch (ret) {
142 : case ERANGE:
143 0 : ERROR("Could not allocate ID for the group - domain full?\n");
144 0 : break;
145 :
146 : case EEXIST:
147 0 : ERROR("A group with the same name or GID already exists\n");
148 0 : break;
149 :
150 : default:
151 0 : DEBUG(SSSDBG_CRIT_FAILURE,
152 : "sysdb operation failed (%d)[%s]\n", ret, strerror(ret));
153 0 : ERROR("Transaction error. Could not add group.\n");
154 0 : break;
155 : }
156 0 : ret = EXIT_FAILURE;
157 0 : goto fini;
158 : }
159 :
160 0 : ret = EXIT_SUCCESS;
161 : fini:
162 0 : talloc_free(tctx);
163 0 : poptFreeContext(pc);
164 0 : exit(ret);
165 : }
166 :
|