~ubuntu-branches/ubuntu/vivid/samba/vivid

« back to all changes in this revision

Viewing changes to source3/rpc_server/epmd.c

  • Committer: Package Import Robot
  • Author(s): Chuck Short
  • Date: 2011-12-21 13:18:04 UTC
  • mfrom: (0.39.21 sid)
  • Revision ID: package-import@ubuntu.com-20111221131804-xtlr39wx6njehxxr
Tags: 2:3.6.1-3ubuntu1
* Merge from Debian testing.  Remaining changes:
  + debian/patches/VERSION.patch:
    - set SAMBA_VERSION_SUFFIX to Ubuntu.
  + debian/patches/error-trans.fix-276472:
    - Add the translation of Unix Error code -ENOTSUP to NT Error Code
    - NT_STATUS_NOT_SUPPORTED to prevent the Permission denied error.
  + debian/smb.conf:
    - add "(Samba, Ubuntu)" to server string.
    - comment out the default [homes] share, and add a comment about
      "valid users = %S" to show users how to restrict access to
      \\server\username to only username.
    - Set 'usershare allow guests', so that usershare admins are 
      allowed to create public shares in addition to authenticated
      ones.
    - add map to guest = Bad user, maps bad username to guest access.
  + debian/samba-common.config:
    - Do not change priority to high if dhclient3 is installed.
    - Use priority medium instead of high for the workgroup question.
  + debian/control:
    - Don't build against or suggest ctdb.
    - Add dependency on samba-common-bin to samba.
  + Add ufw integration:
    - Created debian/samba.ufw.profile
    - debian/rules, debian/samba.dirs, debian/samba.files: install
      profile
    - debian/control: have samba suggest ufw
  + Add apport hook:
    - Created debian/source_samba.py.
    - debian/rules, debian/samba.dirs, debian/samba-common-bin.files: install
  + Switch to upstart:
    - Add debian/samba.{nmbd,smbd}.upstart.
  + debian/samba.logrotate, debian/samba-common.dhcp, debian/samba.if-up:
    - Make them upstart compatible
  + debian/samba.postinst: 
    - Avoid scary pdbedit warnings on first import.
  + debian/samba-common.postinst: Add more informative error message for
    the case where smb.conf was manually deleted
  + debian/patches/fix-debuglevel-name-conflict.patch: don't use 'debug_level'
    as a global variable name in an NSS module 
  + Dropped:
    - debian/patches/error-trans.fix-276472
    - debian/patches/fix-debuglevel-name-conflict.patch

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *  Unix SMB/CIFS implementation.
 
3
 *
 
4
 *  SMBD RPC service callbacks
 
5
 *
 
6
 *  Copyright (c) 2011      Andreas Schneider <asn@samba.org>
 
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 "includes.h"
 
23
 
 
24
#include "serverid.h"
 
25
#include "ntdomain.h"
 
26
#include "../librpc/gen_ndr/srv_epmapper.h"
 
27
#include "rpc_server/rpc_server.h"
 
28
#include "rpc_server/epmapper/srv_epmapper.h"
 
29
#include "messages.h"
 
30
 
 
31
#define DAEMON_NAME "epmd"
 
32
 
 
33
void start_epmd(struct tevent_context *ev_ctx,
 
34
                struct messaging_context *msg_ctx);
 
35
 
 
36
static bool epmd_open_sockets(struct tevent_context *ev_ctx,
 
37
                              struct messaging_context *msg_ctx)
 
38
{
 
39
        uint32_t num_ifs = iface_count();
 
40
        uint16_t port;
 
41
        uint32_t i;
 
42
 
 
43
        if (lp_interfaces() && lp_bind_interfaces_only()) {
 
44
                /*
 
45
                 * We have been given an interfaces line, and been told to only
 
46
                 * bind to those interfaces. Create a socket per interface and
 
47
                 * bind to only these.
 
48
                 */
 
49
 
 
50
                /* Now open a listen socket for each of the interfaces. */
 
51
                for(i = 0; i < num_ifs; i++) {
 
52
                        const struct sockaddr_storage *ifss =
 
53
                                        iface_n_sockaddr_storage(i);
 
54
 
 
55
                        port = setup_dcerpc_ncacn_tcpip_socket(ev_ctx,
 
56
                                                               msg_ctx,
 
57
                                                               ndr_table_epmapper.syntax_id,
 
58
                                                               ifss,
 
59
                                                               135);
 
60
                        if (port == 0) {
 
61
                                return false;
 
62
                        }
 
63
                }
 
64
        } else {
 
65
                const char *sock_addr = lp_socket_address();
 
66
                const char *sock_ptr;
 
67
                char *sock_tok;
 
68
 
 
69
                if (strequal(sock_addr, "0.0.0.0") ||
 
70
                    strequal(sock_addr, "::")) {
 
71
#if HAVE_IPV6
 
72
                        sock_addr = "::";
 
73
#else
 
74
                        sock_addr = "0.0.0.0";
 
75
#endif
 
76
                }
 
77
 
 
78
                for (sock_ptr = sock_addr;
 
79
                     next_token_talloc(talloc_tos(), &sock_ptr, &sock_tok, " \t,");
 
80
                    ) {
 
81
                        struct sockaddr_storage ss;
 
82
 
 
83
                        /* open an incoming socket */
 
84
                        if (!interpret_string_addr(&ss,
 
85
                                                   sock_tok,
 
86
                                                   AI_NUMERICHOST|AI_PASSIVE)) {
 
87
                                continue;
 
88
                        }
 
89
 
 
90
                        port = setup_dcerpc_ncacn_tcpip_socket(ev_ctx,
 
91
                                                               msg_ctx,
 
92
                                                               ndr_table_epmapper.syntax_id,
 
93
                                                               &ss,
 
94
                                                               135);
 
95
                        if (port == 0) {
 
96
                                return false;
 
97
                        }
 
98
                }
 
99
        }
 
100
 
 
101
        return true;
 
102
}
 
103
 
 
104
static void epmd_reopen_logs(void)
 
105
{
 
106
        char *lfile = lp_logfile();
 
107
        int rc;
 
108
 
 
109
        if (lfile == NULL || lfile[0] == '\0') {
 
110
                rc = asprintf(&lfile, "%s/log.%s", get_dyn_LOGFILEBASE(), DAEMON_NAME);
 
111
                if (rc > 0) {
 
112
                        lp_set_logfile(lfile);
 
113
                        SAFE_FREE(lfile);
 
114
                }
 
115
        } else {
 
116
                if (strstr(lfile, DAEMON_NAME) == NULL) {
 
117
                        rc = asprintf(&lfile, "%s.%s", lp_logfile(), DAEMON_NAME);
 
118
                        if (rc > 0) {
 
119
                                lp_set_logfile(lfile);
 
120
                                SAFE_FREE(lfile);
 
121
                        }
 
122
                }
 
123
        }
 
124
 
 
125
        reopen_logs();
 
126
}
 
127
 
 
128
static void epmd_smb_conf_updated(struct messaging_context *msg,
 
129
                                  void *private_data,
 
130
                                  uint32_t msg_type,
 
131
                                  struct server_id server_id,
 
132
                                  DATA_BLOB *data)
 
133
{
 
134
        DEBUG(10, ("Got message saying smb.conf was updated. Reloading.\n"));
 
135
        change_to_root_user();
 
136
        epmd_reopen_logs();
 
137
}
 
138
 
 
139
static void epmd_sig_term_handler(struct tevent_context *ev,
 
140
                                  struct tevent_signal *se,
 
141
                                  int signum,
 
142
                                  int count,
 
143
                                  void *siginfo,
 
144
                                  void *private_data)
 
145
{
 
146
        rpc_epmapper_shutdown();
 
147
 
 
148
        exit_server_cleanly("termination signal");
 
149
}
 
150
 
 
151
static void epmd_setup_sig_term_handler(struct tevent_context *ev_ctx)
 
152
{
 
153
        struct tevent_signal *se;
 
154
 
 
155
        se = tevent_add_signal(ev_ctx,
 
156
                               ev_ctx,
 
157
                               SIGTERM, 0,
 
158
                               epmd_sig_term_handler,
 
159
                               NULL);
 
160
        if (se == NULL) {
 
161
                exit_server("failed to setup SIGTERM handler");
 
162
        }
 
163
}
 
164
 
 
165
static void epmd_sig_hup_handler(struct tevent_context *ev,
 
166
                                    struct tevent_signal *se,
 
167
                                    int signum,
 
168
                                    int count,
 
169
                                    void *siginfo,
 
170
                                    void *private_data)
 
171
{
 
172
        change_to_root_user();
 
173
 
 
174
        DEBUG(1,("Reloading printers after SIGHUP\n"));
 
175
        epmd_reopen_logs();
 
176
}
 
177
 
 
178
static void epmd_setup_sig_hup_handler(struct tevent_context *ev_ctx,
 
179
                                       struct messaging_context *msg_ctx)
 
180
{
 
181
        struct tevent_signal *se;
 
182
 
 
183
        se = tevent_add_signal(ev_ctx,
 
184
                               ev_ctx,
 
185
                               SIGHUP, 0,
 
186
                               epmd_sig_hup_handler,
 
187
                               msg_ctx);
 
188
        if (se == NULL) {
 
189
                exit_server("failed to setup SIGHUP handler");
 
190
        }
 
191
}
 
192
 
 
193
static bool epmapper_shutdown_cb(void *ptr) {
 
194
        srv_epmapper_cleanup();
 
195
 
 
196
        return true;
 
197
}
 
198
 
 
199
void start_epmd(struct tevent_context *ev_ctx,
 
200
                struct messaging_context *msg_ctx)
 
201
{
 
202
        struct rpc_srv_callbacks epmapper_cb;
 
203
        NTSTATUS status;
 
204
        pid_t pid;
 
205
        bool ok;
 
206
        int rc;
 
207
 
 
208
        epmapper_cb.init = NULL;
 
209
        epmapper_cb.shutdown = epmapper_shutdown_cb;
 
210
        epmapper_cb.private_data = NULL;
 
211
 
 
212
        DEBUG(1, ("Forking Endpoint Mapper Daemon\n"));
 
213
 
 
214
        pid = sys_fork();
 
215
 
 
216
        if (pid == -1) {
 
217
                DEBUG(0, ("Failed to fork Endpoint Mapper [%s], aborting ...\n",
 
218
                          strerror(errno)));
 
219
                exit(1);
 
220
        }
 
221
 
 
222
        if (pid) {
 
223
                /* parent */
 
224
                return;
 
225
        }
 
226
 
 
227
        /* child */
 
228
        close_low_fds(false);
 
229
 
 
230
        status = reinit_after_fork(msg_ctx,
 
231
                                   ev_ctx,
 
232
                                   procid_self(),
 
233
                                   true);
 
234
        if (!NT_STATUS_IS_OK(status)) {
 
235
                DEBUG(0,("reinit_after_fork() failed\n"));
 
236
                smb_panic("reinit_after_fork() failed");
 
237
        }
 
238
 
 
239
        epmd_reopen_logs();
 
240
 
 
241
        epmd_setup_sig_term_handler(ev_ctx);
 
242
        epmd_setup_sig_hup_handler(ev_ctx, msg_ctx);
 
243
 
 
244
        ok = serverid_register(procid_self(),
 
245
                               FLAG_MSG_GENERAL|FLAG_MSG_SMBD
 
246
                               |FLAG_MSG_PRINT_GENERAL);
 
247
        if (!ok) {
 
248
                DEBUG(0, ("Failed to register serverid in epmd!\n"));
 
249
                exit(1);
 
250
        }
 
251
 
 
252
        messaging_register(msg_ctx,
 
253
                           ev_ctx,
 
254
                           MSG_SMB_CONF_UPDATED,
 
255
                           epmd_smb_conf_updated);
 
256
 
 
257
        status = rpc_epmapper_init(&epmapper_cb);
 
258
        if (!NT_STATUS_IS_OK(status)) {
 
259
                DEBUG(0, ("Failed to register epmd rpc inteface! (%s)\n",
 
260
                          nt_errstr(status)));
 
261
                exit(1);
 
262
        }
 
263
 
 
264
        ok = setup_dcerpc_ncalrpc_socket(ev_ctx,
 
265
                                         msg_ctx,
 
266
                                         ndr_table_epmapper.syntax_id,
 
267
                                         "EPMAPPER",
 
268
                                         srv_epmapper_delete_endpoints);
 
269
        if (!ok) {
 
270
                DEBUG(0, ("Failed to open epmd ncalrpc pipe!\n"));
 
271
                exit(1);
 
272
        }
 
273
 
 
274
        ok = epmd_open_sockets(ev_ctx, msg_ctx);
 
275
        if (!ok) {
 
276
                DEBUG(0, ("Failed to open epmd tcpip sockets!\n"));
 
277
                exit(1);
 
278
        }
 
279
 
 
280
        ok = setup_named_pipe_socket("epmapper", ev_ctx);
 
281
        if (!ok) {
 
282
                DEBUG(0, ("Failed to open epmd named pipe!\n"));
 
283
                exit(1);
 
284
        }
 
285
 
 
286
        DEBUG(1, ("Endpoint Mapper Daemon Started (%d)\n", getpid()));
 
287
 
 
288
        /* loop forever */
 
289
        rc = tevent_loop_wait(ev_ctx);
 
290
 
 
291
        /* should not be reached */
 
292
        DEBUG(0,("background_queue: tevent_loop_wait() exited with %d - %s\n",
 
293
                 rc, (rc == 0) ? "out of events" : strerror(errno)));
 
294
 
 
295
        exit(1);
 
296
}
 
297
 
 
298
/* vim: set ts=8 sw=8 noet cindent ft=c.doxygen: */