Line data Source code
1 : /*
2 : Authors:
3 : Pavel Březina <pbrezina@redhat.com>
4 :
5 : Copyright (C) 2011 Red Hat
6 :
7 : This program is free software; you can redistribute it and/or modify
8 : it under the terms of the GNU General Public License as published by
9 : the Free Software Foundation; either version 3 of the License, or
10 : (at your option) any later version.
11 :
12 : This program is distributed in the hope that it will be useful,
13 : but WITHOUT ANY WARRANTY; without even the implied warranty of
14 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 : GNU General Public License for more details.
16 :
17 : You should have received a copy of the GNU General Public License
18 : along with this program. If not, see <http://www.gnu.org/licenses/>.
19 : */
20 :
21 : #include <popt.h>
22 :
23 : #include "util/util.h"
24 : #include "confdb/confdb.h"
25 : #include "monitor/monitor_interfaces.h"
26 : #include "responder/common/responder.h"
27 : #include "responder/common/responder_sbus.h"
28 : #include "responder/sudo/sudosrv_private.h"
29 : #include "providers/data_provider.h"
30 : #include "responder/common/negcache.h"
31 :
32 : struct mon_cli_iface monitor_sudo_methods = {
33 : { &mon_cli_iface_meta, 0 },
34 : .ping = monitor_common_pong,
35 : .resInit = monitor_common_res_init,
36 : .shutDown = NULL,
37 : .goOffline = NULL,
38 : .resetOffline = NULL,
39 : .rotateLogs = responder_logrotate,
40 : .clearMemcache = NULL,
41 : .clearEnumCache = NULL,
42 : .sysbusReconnect = NULL,
43 : };
44 :
45 : static struct data_provider_iface sudo_dp_methods = {
46 : { &data_provider_iface_meta, 0 },
47 : .RegisterService = NULL,
48 : .pamHandler = NULL,
49 : .sudoHandler = NULL,
50 : .autofsHandler = NULL,
51 : .hostHandler = NULL,
52 : .getDomains = NULL,
53 : .getAccountInfo = NULL,
54 : };
55 :
56 0 : static void sudo_dp_reconnect_init(struct sbus_connection *conn,
57 : int status,
58 : void *pvt)
59 : {
60 0 : struct be_conn *be_conn = talloc_get_type(pvt, struct be_conn);
61 : int ret;
62 :
63 : /* Did we reconnect successfully? */
64 0 : if (status == SBUS_RECONNECT_SUCCESS) {
65 0 : DEBUG(SSSDBG_TRACE_FUNC, "Reconnected to the Data Provider.\n");
66 :
67 : /* Identify ourselves to the data provider */
68 0 : ret = dp_common_send_id(be_conn->conn,
69 : DATA_PROVIDER_VERSION,
70 : "SUDO");
71 : /* all fine */
72 0 : if (ret == EOK) {
73 0 : handle_requests_after_reconnect(be_conn->rctx);
74 0 : return;
75 : }
76 : }
77 :
78 : /* Failed to reconnect */
79 0 : DEBUG(SSSDBG_FATAL_FAILURE, "Could not reconnect to %s provider.\n",
80 : be_conn->domain->name);
81 : }
82 :
83 0 : int sudo_process_init(TALLOC_CTX *mem_ctx,
84 : struct tevent_context *ev,
85 : struct confdb_ctx *cdb)
86 : {
87 : struct resp_ctx *rctx;
88 : struct sss_cmd_table *sudo_cmds;
89 : struct sudo_ctx *sudo_ctx;
90 : struct be_conn *iter;
91 : int ret;
92 : int max_retries;
93 :
94 0 : sudo_cmds = get_sudo_cmds();
95 0 : ret = sss_process_init(mem_ctx, ev, cdb,
96 : sudo_cmds,
97 : SSS_SUDO_SOCKET_NAME, -1, NULL, -1,
98 : CONFDB_SUDO_CONF_ENTRY,
99 : SSS_SUDO_SBUS_SERVICE_NAME,
100 : SSS_SUDO_SBUS_SERVICE_VERSION,
101 : &monitor_sudo_methods,
102 : "SUDO",
103 : &sudo_dp_methods.vtable,
104 : &rctx);
105 0 : if (ret != EOK) {
106 0 : DEBUG(SSSDBG_FATAL_FAILURE, "sss_process_init() failed\n");
107 0 : return ret;
108 : }
109 :
110 0 : sudo_ctx = talloc_zero(rctx, struct sudo_ctx);
111 0 : if (!sudo_ctx) {
112 0 : DEBUG(SSSDBG_FATAL_FAILURE, "fatal error initializing sudo_ctx\n");
113 0 : ret = ENOMEM;
114 0 : goto fail;
115 : }
116 :
117 0 : ret = sss_ncache_init(rctx, &sudo_ctx->ncache);
118 0 : if (ret != EOK) {
119 0 : DEBUG(SSSDBG_FATAL_FAILURE,
120 : "fatal error initializing ncache\n");
121 0 : goto fail;
122 : }
123 :
124 0 : sudo_ctx->rctx = rctx;
125 0 : sudo_ctx->rctx->pvt_ctx = sudo_ctx;
126 :
127 0 : ret = confdb_get_int(cdb, CONFDB_NSS_CONF_ENTRY,
128 : CONFDB_NSS_ENTRY_NEG_TIMEOUT, 15,
129 : &sudo_ctx->neg_timeout);
130 0 : if (ret != EOK) {
131 0 : DEBUG(SSSDBG_FATAL_FAILURE,
132 : "fatal error getting ncache timeout\n");
133 0 : goto fail;
134 : }
135 :
136 0 : sss_ncache_prepopulate(sudo_ctx->ncache, sudo_ctx->rctx->cdb, rctx);
137 0 : if (ret != EOK) {
138 0 : DEBUG(SSSDBG_FATAL_FAILURE,
139 : "failed to set ncache for sudo's filter_users\n");
140 0 : goto fail;
141 : }
142 :
143 : /* Enable automatic reconnection to the Data Provider */
144 0 : ret = confdb_get_int(sudo_ctx->rctx->cdb,
145 : CONFDB_SUDO_CONF_ENTRY,
146 : CONFDB_SERVICE_RECON_RETRIES,
147 : 3, &max_retries);
148 0 : if (ret != EOK) {
149 0 : DEBUG(SSSDBG_FATAL_FAILURE,
150 : "Failed to set up automatic reconnection\n");
151 0 : goto fail;
152 : }
153 :
154 0 : for (iter = sudo_ctx->rctx->be_conns; iter; iter = iter->next) {
155 0 : sbus_reconnect_init(iter->conn, max_retries,
156 : sudo_dp_reconnect_init, iter);
157 : }
158 :
159 : /* Get sudo_timed option */
160 0 : ret = confdb_get_bool(sudo_ctx->rctx->cdb,
161 : CONFDB_SUDO_CONF_ENTRY, CONFDB_SUDO_TIMED,
162 : CONFDB_DEFAULT_SUDO_TIMED,
163 : &sudo_ctx->timed);
164 0 : if (ret != EOK) {
165 0 : DEBUG(SSSDBG_FATAL_FAILURE, "Error reading from confdb (%d) [%s]\n",
166 : ret, strerror(ret));
167 0 : goto fail;
168 : }
169 :
170 : /* Get sudo_inverse_order option */
171 0 : ret = confdb_get_bool(sudo_ctx->rctx->cdb,
172 : CONFDB_SUDO_CONF_ENTRY, CONFDB_SUDO_INVERSE_ORDER,
173 : CONFDB_DEFAULT_SUDO_INVERSE_ORDER,
174 : &sudo_ctx->inverse_order);
175 0 : if (ret != EOK) {
176 0 : DEBUG(SSSDBG_FATAL_FAILURE, "Error reading from confdb (%d) [%s]\n",
177 : ret, strerror(ret));
178 0 : goto fail;
179 : }
180 :
181 0 : ret = schedule_get_domains_task(rctx, rctx->ev, rctx, NULL);
182 0 : if (ret != EOK) {
183 0 : DEBUG(SSSDBG_FATAL_FAILURE, "schedule_get_domains_tasks failed.\n");
184 0 : goto fail;
185 : }
186 :
187 0 : DEBUG(SSSDBG_TRACE_FUNC, "SUDO Initialization complete\n");
188 :
189 0 : return EOK;
190 :
191 : fail:
192 0 : talloc_free(rctx);
193 0 : return ret;
194 : }
195 :
196 0 : int main(int argc, const char *argv[])
197 : {
198 : int opt;
199 : poptContext pc;
200 : struct main_context *main_ctx;
201 : int ret;
202 : uid_t uid;
203 : gid_t gid;
204 :
205 0 : struct poptOption long_options[] = {
206 : POPT_AUTOHELP
207 0 : SSSD_MAIN_OPTS
208 0 : SSSD_SERVER_OPTS(uid, gid)
209 : POPT_TABLEEND
210 : };
211 :
212 : /* Set debug level to invalid value so we can deside if -d 0 was used. */
213 0 : debug_level = SSSDBG_INVALID;
214 :
215 0 : umask(DFL_RSP_UMASK);
216 :
217 0 : pc = poptGetContext(argv[0], argc, argv, long_options, 0);
218 0 : while((opt = poptGetNextOpt(pc)) != -1) {
219 : switch(opt) {
220 : default:
221 0 : fprintf(stderr, "\nInvalid option %s: %s\n\n",
222 : poptBadOption(pc, 0), poptStrerror(opt));
223 0 : poptPrintUsage(pc, stderr, 0);
224 0 : return 1;
225 : }
226 : }
227 :
228 0 : poptFreeContext(pc);
229 :
230 0 : DEBUG_INIT(debug_level);
231 :
232 : /* set up things like debug, signals, daemonization, etc... */
233 0 : debug_log_file = "sssd_sudo";
234 :
235 0 : ret = server_setup("sssd[sudo]", 0, uid, gid, CONFDB_SUDO_CONF_ENTRY,
236 : &main_ctx);
237 0 : if (ret != EOK) {
238 0 : return 2;
239 : }
240 :
241 0 : ret = die_if_parent_died();
242 0 : if (ret != EOK) {
243 : /* This is not fatal, don't return */
244 0 : DEBUG(SSSDBG_OP_FAILURE, "Could not set up to exit "
245 : "when parent process does\n");
246 : }
247 :
248 0 : ret = sudo_process_init(main_ctx,
249 0 : main_ctx->event_ctx,
250 0 : main_ctx->confdb_ctx);
251 0 : if (ret != EOK) {
252 0 : return 3;
253 : }
254 :
255 : /* loop on main */
256 0 : server_loop(main_ctx);
257 :
258 0 : return 0;
259 : }
|