Line data Source code
1 : /*
2 : Authors:
3 : Jan Cholasta <jcholast@redhat.com>
4 :
5 : Copyright (C) 2012 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/ssh/sshsrv_private.h"
29 : #include "providers/data_provider.h"
30 :
31 : struct mon_cli_iface monitor_ssh_methods = {
32 : { &mon_cli_iface_meta, 0 },
33 : .ping = monitor_common_pong,
34 : .resInit = monitor_common_res_init,
35 : .shutDown = NULL,
36 : .goOffline = NULL,
37 : .resetOffline = NULL,
38 : .rotateLogs = responder_logrotate,
39 : .clearMemcache = NULL,
40 : .clearEnumCache = NULL,
41 : .sysbusReconnect = NULL,
42 : };
43 :
44 : static struct data_provider_iface ssh_dp_methods = {
45 : { &data_provider_iface_meta, 0 },
46 : .RegisterService = NULL,
47 : .pamHandler = NULL,
48 : .sudoHandler = NULL,
49 : .autofsHandler = NULL,
50 : .hostHandler = NULL,
51 : .getDomains = NULL,
52 : .getAccountInfo = NULL,
53 : };
54 :
55 0 : static void ssh_dp_reconnect_init(struct sbus_connection *conn,
56 : int status, void *pvt)
57 : {
58 0 : struct be_conn *be_conn = talloc_get_type(pvt, struct be_conn);
59 : int ret;
60 :
61 : /* Did we reconnect successfully? */
62 0 : if (status == SBUS_RECONNECT_SUCCESS) {
63 0 : DEBUG(SSSDBG_TRACE_FUNC, "Reconnected to the Data Provider.\n");
64 :
65 : /* Identify ourselves to the data provider */
66 0 : ret = dp_common_send_id(be_conn->conn,
67 : DATA_PROVIDER_VERSION,
68 : "SSH");
69 : /* all fine */
70 0 : if (ret == EOK) {
71 0 : handle_requests_after_reconnect(be_conn->rctx);
72 0 : return;
73 : }
74 : }
75 :
76 : /* Failed to reconnect */
77 0 : DEBUG(SSSDBG_FATAL_FAILURE, "Could not reconnect to %s provider.\n",
78 : be_conn->domain->name);
79 : }
80 :
81 0 : int ssh_process_init(TALLOC_CTX *mem_ctx,
82 : struct tevent_context *ev,
83 : struct confdb_ctx *cdb)
84 : {
85 : struct resp_ctx *rctx;
86 : struct sss_cmd_table *ssh_cmds;
87 : struct ssh_ctx *ssh_ctx;
88 : struct be_conn *iter;
89 : int ret;
90 : int max_retries;
91 :
92 0 : ssh_cmds = get_ssh_cmds();
93 0 : ret = sss_process_init(mem_ctx, ev, cdb,
94 : ssh_cmds,
95 : SSS_SSH_SOCKET_NAME, -1, NULL, -1,
96 : CONFDB_SSH_CONF_ENTRY,
97 : SSS_SSH_SBUS_SERVICE_NAME,
98 : SSS_SSH_SBUS_SERVICE_VERSION,
99 : &monitor_ssh_methods,
100 : "SSH",
101 : &ssh_dp_methods.vtable,
102 : &rctx);
103 0 : if (ret != EOK) {
104 0 : DEBUG(SSSDBG_FATAL_FAILURE, "sss_process_init() failed\n");
105 0 : return ret;
106 : }
107 :
108 0 : ssh_ctx = talloc_zero(rctx, struct ssh_ctx);
109 0 : if (!ssh_ctx) {
110 0 : DEBUG(SSSDBG_FATAL_FAILURE, "fatal error initializing ssh_ctx\n");
111 0 : ret = ENOMEM;
112 0 : goto fail;
113 : }
114 :
115 0 : ssh_ctx->rctx = rctx;
116 0 : ssh_ctx->rctx->pvt_ctx = ssh_ctx;
117 :
118 0 : ret = sss_names_init_from_args(ssh_ctx,
119 : "(?P<name>[^@]+)@?(?P<domain>[^@]*$)",
120 : "%1$s@%2$s", &ssh_ctx->snctx);
121 0 : if (ret != EOK) {
122 0 : DEBUG(SSSDBG_FATAL_FAILURE, "fatal error initializing regex data\n");
123 0 : goto fail;
124 : }
125 :
126 : /* Enable automatic reconnection to the Data Provider */
127 0 : ret = confdb_get_int(ssh_ctx->rctx->cdb,
128 : CONFDB_SSH_CONF_ENTRY,
129 : CONFDB_SERVICE_RECON_RETRIES,
130 : 3, &max_retries);
131 0 : if (ret != EOK) {
132 0 : DEBUG(SSSDBG_FATAL_FAILURE,
133 : "Failed to set up automatic reconnection\n");
134 0 : goto fail;
135 : }
136 :
137 0 : for (iter = ssh_ctx->rctx->be_conns; iter; iter = iter->next) {
138 0 : sbus_reconnect_init(iter->conn, max_retries,
139 : ssh_dp_reconnect_init, iter);
140 : }
141 :
142 : /* Get responder options */
143 :
144 : /* Get ssh_hash_known_hosts option */
145 0 : ret = confdb_get_bool(ssh_ctx->rctx->cdb,
146 : CONFDB_SSH_CONF_ENTRY, CONFDB_SSH_HASH_KNOWN_HOSTS,
147 : CONFDB_DEFAULT_SSH_HASH_KNOWN_HOSTS,
148 : &ssh_ctx->hash_known_hosts);
149 0 : if (ret != EOK) {
150 0 : DEBUG(SSSDBG_FATAL_FAILURE, "Error reading from confdb (%d) [%s]\n",
151 : ret, strerror(ret));
152 0 : goto fail;
153 : }
154 :
155 : /* Get ssh_known_hosts_timeout option */
156 0 : ret = confdb_get_int(ssh_ctx->rctx->cdb,
157 : CONFDB_SSH_CONF_ENTRY, CONFDB_SSH_KNOWN_HOSTS_TIMEOUT,
158 : CONFDB_DEFAULT_SSH_KNOWN_HOSTS_TIMEOUT,
159 : &ssh_ctx->known_hosts_timeout);
160 0 : if (ret != EOK) {
161 0 : DEBUG(SSSDBG_FATAL_FAILURE, "Error reading from confdb (%d) [%s]\n",
162 : ret, strerror(ret));
163 0 : goto fail;
164 : }
165 :
166 0 : ret = confdb_get_string(ssh_ctx->rctx->cdb, ssh_ctx,
167 : CONFDB_SSH_CONF_ENTRY, CONFDB_SSH_CA_DB,
168 : CONFDB_DEFAULT_SSH_CA_DB, &ssh_ctx->ca_db);
169 0 : if (ret != EOK) {
170 0 : DEBUG(SSSDBG_FATAL_FAILURE, "Error reading CA DB from confdb (%d) [%s]\n",
171 : ret, strerror(ret));
172 0 : goto fail;
173 : }
174 :
175 0 : ret = schedule_get_domains_task(rctx, rctx->ev, rctx, NULL);
176 0 : if (ret != EOK) {
177 0 : DEBUG(SSSDBG_FATAL_FAILURE, "schedule_get_domains_tasks failed.\n");
178 0 : goto fail;
179 : }
180 :
181 0 : DEBUG(SSSDBG_TRACE_FUNC, "SSH Initialization complete\n");
182 :
183 0 : return EOK;
184 :
185 : fail:
186 0 : talloc_free(rctx);
187 0 : return ret;
188 : }
189 :
190 0 : int main(int argc, const char *argv[])
191 : {
192 : int opt;
193 : poptContext pc;
194 : struct main_context *main_ctx;
195 : int ret;
196 : uid_t uid;
197 : gid_t gid;
198 :
199 0 : struct poptOption long_options[] = {
200 : POPT_AUTOHELP
201 0 : SSSD_MAIN_OPTS
202 0 : SSSD_SERVER_OPTS(uid, gid)
203 : POPT_TABLEEND
204 : };
205 :
206 : /* Set debug level to invalid value so we can deside if -d 0 was used. */
207 0 : debug_level = SSSDBG_INVALID;
208 :
209 0 : umask(DFL_RSP_UMASK);
210 :
211 0 : pc = poptGetContext(argv[0], argc, argv, long_options, 0);
212 0 : while((opt = poptGetNextOpt(pc)) != -1) {
213 : switch(opt) {
214 : default:
215 0 : fprintf(stderr, "\nInvalid option %s: %s\n\n",
216 : poptBadOption(pc, 0), poptStrerror(opt));
217 0 : poptPrintUsage(pc, stderr, 0);
218 0 : return 1;
219 : }
220 : }
221 :
222 0 : poptFreeContext(pc);
223 :
224 0 : DEBUG_INIT(debug_level);
225 :
226 : /* set up things like debug, signals, daemonization, etc... */
227 0 : debug_log_file = "sssd_ssh";
228 :
229 0 : ret = server_setup("sssd[ssh]", 0, uid, gid,
230 : CONFDB_SSH_CONF_ENTRY, &main_ctx);
231 0 : if (ret != EOK) {
232 0 : return 2;
233 : }
234 :
235 0 : ret = die_if_parent_died();
236 0 : if (ret != EOK) {
237 : /* This is not fatal, don't return */
238 0 : DEBUG(SSSDBG_OP_FAILURE, "Could not set up to exit "
239 : "when parent process does\n");
240 : }
241 :
242 0 : ret = ssh_process_init(main_ctx,
243 0 : main_ctx->event_ctx,
244 0 : main_ctx->confdb_ctx);
245 0 : if (ret != EOK) {
246 0 : return 3;
247 : }
248 :
249 : /* loop on main */
250 0 : server_loop(main_ctx);
251 :
252 0 : return 0;
253 : }
|