Line data Source code
1 : /*
2 : Authors:
3 : Jakub Hrozek <jhrozek@redhat.com>
4 :
5 : Copyright (C) 2012 Red Hat
6 :
7 : Autofs responder: the responder server
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 <popt.h>
24 :
25 : #include "util/util.h"
26 : #include "confdb/confdb.h"
27 : #include "monitor/monitor_interfaces.h"
28 : #include "responder/common/responder.h"
29 : #include "providers/data_provider.h"
30 : #include "responder/autofs/autofs_private.h"
31 :
32 : static int autofs_clean_hash_table(struct sbus_request *dbus_req, void *data);
33 :
34 : struct mon_cli_iface monitor_autofs_methods = {
35 : { &mon_cli_iface_meta, 0 },
36 : .ping = monitor_common_pong,
37 : .resInit = monitor_common_res_init,
38 : .shutDown = NULL,
39 : .goOffline = NULL,
40 : .resetOffline = NULL,
41 : .rotateLogs = responder_logrotate,
42 : .clearMemcache = NULL,
43 : .clearEnumCache = autofs_clean_hash_table,
44 : .sysbusReconnect = NULL,
45 : };
46 :
47 : static struct data_provider_iface autofs_dp_methods = {
48 : { &data_provider_iface_meta, 0 },
49 : .RegisterService = NULL,
50 : .pamHandler = NULL,
51 : .sudoHandler = NULL,
52 : .autofsHandler = NULL,
53 : .hostHandler = NULL,
54 : .getDomains = NULL,
55 : .getAccountInfo = NULL,
56 : };
57 :
58 : static errno_t
59 0 : autofs_get_config(struct autofs_ctx *actx,
60 : struct confdb_ctx *cdb)
61 : {
62 : errno_t ret;
63 :
64 0 : ret = confdb_get_int(cdb, CONFDB_AUTOFS_CONF_ENTRY,
65 : CONFDB_AUTOFS_MAP_NEG_TIMEOUT, 15,
66 : &actx->neg_timeout);
67 0 : if (ret != EOK) {
68 0 : DEBUG(SSSDBG_OP_FAILURE, "Cannot read %s from configuration [%d]: %s\n",
69 : CONFDB_AUTOFS_MAP_NEG_TIMEOUT, ret, strerror(ret));
70 0 : return ret;
71 : }
72 :
73 0 : return EOK;
74 : }
75 :
76 : static void
77 0 : autofs_dp_reconnect_init(struct sbus_connection *conn,
78 : int status, void *pvt)
79 : {
80 0 : struct be_conn *be_conn = talloc_get_type(pvt, struct be_conn);
81 : int ret;
82 :
83 : /* Did we reconnect successfully? */
84 0 : if (status == SBUS_RECONNECT_SUCCESS) {
85 0 : DEBUG(SSSDBG_TRACE_FUNC, "Reconnected to the Data Provider.\n");
86 :
87 : /* Identify ourselves to the data provider */
88 0 : ret = dp_common_send_id(be_conn->conn,
89 : DATA_PROVIDER_VERSION,
90 : "autofs");
91 : /* all fine */
92 0 : if (ret == EOK) {
93 0 : handle_requests_after_reconnect(be_conn->rctx);
94 0 : return;
95 : }
96 : }
97 :
98 : /* Failed to reconnect */
99 0 : DEBUG(SSSDBG_FATAL_FAILURE, "Could not reconnect to %s provider.\n",
100 : be_conn->domain->name);
101 : }
102 :
103 0 : static int autofs_clean_hash_table(struct sbus_request *dbus_req, void *data)
104 : {
105 0 : struct resp_ctx *rctx = talloc_get_type(data, struct resp_ctx);
106 0 : struct autofs_ctx *actx =
107 0 : talloc_get_type(rctx->pvt_ctx, struct autofs_ctx);
108 : errno_t ret;
109 :
110 0 : ret = autofs_orphan_maps(actx);
111 0 : if (ret != EOK) {
112 0 : DEBUG(SSSDBG_OP_FAILURE, "Could not invalidate maps\n");
113 0 : return ret;
114 : }
115 :
116 0 : return sbus_request_return_and_finish(dbus_req, DBUS_TYPE_INVALID);
117 : }
118 :
119 : static int
120 0 : autofs_process_init(TALLOC_CTX *mem_ctx,
121 : struct tevent_context *ev,
122 : struct confdb_ctx *cdb)
123 : {
124 : struct resp_ctx *rctx;
125 : struct sss_cmd_table *autofs_cmds;
126 : struct autofs_ctx *autofs_ctx;
127 : struct be_conn *iter;
128 : int ret;
129 : int hret;
130 : int max_retries;
131 :
132 0 : autofs_cmds = get_autofs_cmds();
133 0 : ret = sss_process_init(mem_ctx, ev, cdb,
134 : autofs_cmds,
135 : SSS_AUTOFS_SOCKET_NAME, -1, NULL, -1,
136 : CONFDB_AUTOFS_CONF_ENTRY,
137 : SSS_AUTOFS_SBUS_SERVICE_NAME,
138 : SSS_AUTOFS_SBUS_SERVICE_VERSION,
139 : &monitor_autofs_methods,
140 : "autofs",
141 : &autofs_dp_methods.vtable,
142 : &rctx);
143 0 : if (ret != EOK) {
144 0 : DEBUG(SSSDBG_FATAL_FAILURE, "sss_process_init() failed\n");
145 0 : return ret;
146 : }
147 :
148 0 : autofs_ctx = talloc_zero(rctx, struct autofs_ctx);
149 0 : if (!autofs_ctx) {
150 0 : DEBUG(SSSDBG_FATAL_FAILURE, "fatal error initializing autofs_ctx\n");
151 0 : ret = ENOMEM;
152 0 : goto fail;
153 : }
154 :
155 0 : ret = autofs_get_config(autofs_ctx, cdb);
156 0 : if (ret != EOK) {
157 0 : DEBUG(SSSDBG_FATAL_FAILURE, "Cannot read autofs configuration\n");
158 0 : goto fail;
159 : }
160 :
161 0 : autofs_ctx->rctx = rctx;
162 0 : autofs_ctx->rctx->pvt_ctx = autofs_ctx;
163 :
164 : /* Enable automatic reconnection to the Data Provider */
165 0 : ret = confdb_get_int(autofs_ctx->rctx->cdb,
166 : CONFDB_AUTOFS_CONF_ENTRY,
167 : CONFDB_SERVICE_RECON_RETRIES,
168 : 3, &max_retries);
169 0 : if (ret != EOK) {
170 0 : DEBUG(SSSDBG_FATAL_FAILURE,
171 : "Failed to set up automatic reconnection\n");
172 0 : goto fail;
173 : }
174 :
175 0 : for (iter = autofs_ctx->rctx->be_conns; iter; iter = iter->next) {
176 0 : sbus_reconnect_init(iter->conn, max_retries,
177 : autofs_dp_reconnect_init, iter);
178 : }
179 :
180 : /* Create the lookup table for setautomntent results */
181 0 : hret = sss_hash_create_ex(autofs_ctx, 10, &autofs_ctx->maps, 0, 0, 0, 0,
182 : autofs_map_hash_delete_cb, NULL);
183 0 : if (hret != HASH_SUCCESS) {
184 0 : DEBUG(SSSDBG_CRIT_FAILURE,
185 : "Unable to initialize automount maps hash table\n");
186 0 : ret = EIO;
187 0 : goto fail;
188 : }
189 :
190 0 : ret = schedule_get_domains_task(rctx, rctx->ev, rctx, NULL);
191 0 : if (ret != EOK) {
192 0 : DEBUG(SSSDBG_FATAL_FAILURE, "schedule_get_domains_tasks failed.\n");
193 0 : goto fail;
194 : }
195 :
196 0 : DEBUG(SSSDBG_TRACE_FUNC, "autofs Initialization complete\n");
197 0 : return EOK;
198 :
199 : fail:
200 0 : talloc_free(rctx);
201 0 : return ret;
202 : }
203 :
204 0 : int main(int argc, const char *argv[])
205 : {
206 : int opt;
207 : poptContext pc;
208 : struct main_context *main_ctx;
209 : int ret;
210 : uid_t uid;
211 : gid_t gid;
212 :
213 0 : struct poptOption long_options[] = {
214 : POPT_AUTOHELP
215 0 : SSSD_MAIN_OPTS
216 0 : SSSD_SERVER_OPTS(uid, gid)
217 : POPT_TABLEEND
218 : };
219 :
220 : /* Set debug level to invalid value so we can decide if -d 0 was used. */
221 0 : debug_level = SSSDBG_INVALID;
222 :
223 0 : umask(DFL_RSP_UMASK);
224 :
225 0 : pc = poptGetContext(argv[0], argc, argv, long_options, 0);
226 0 : while((opt = poptGetNextOpt(pc)) != -1) {
227 : switch(opt) {
228 : default:
229 0 : fprintf(stderr, "\nInvalid option %s: %s\n\n",
230 : poptBadOption(pc, 0), poptStrerror(opt));
231 0 : poptPrintUsage(pc, stderr, 0);
232 0 : return 1;
233 : }
234 : }
235 :
236 0 : poptFreeContext(pc);
237 :
238 0 : DEBUG_INIT(debug_level);
239 :
240 : /* set up things like debug, signals, daemonization, etc... */
241 0 : debug_log_file = "sssd_autofs";
242 :
243 0 : ret = server_setup("sssd[autofs]", 0, uid, gid,
244 : CONFDB_AUTOFS_CONF_ENTRY, &main_ctx);
245 0 : if (ret != EOK) {
246 0 : return 2;
247 : }
248 :
249 0 : ret = die_if_parent_died();
250 0 : if (ret != EOK) {
251 : /* This is not fatal, don't return */
252 0 : DEBUG(SSSDBG_OP_FAILURE, "Could not set up to exit "
253 : "when parent process does\n");
254 : }
255 :
256 0 : ret = autofs_process_init(main_ctx,
257 0 : main_ctx->event_ctx,
258 0 : main_ctx->confdb_ctx);
259 0 : if (ret != EOK) {
260 0 : return 3;
261 : }
262 :
263 : /* loop on main */
264 0 : server_loop(main_ctx);
265 :
266 0 : return 0;
267 : }
|