~ubuntu-branches/ubuntu/lucid/samba/lucid-security

« back to all changes in this revision

Viewing changes to .pc/security-CVE-2010-0728.patch/source3/smbd/server.c

  • Committer: Bazaar Package Importer
  • Author(s): Marc Deslauriers
  • Date: 2010-03-08 17:50:57 UTC
  • Revision ID: james.westby@ubuntu.com-20100308175057-z5ao2e65nqgiovbn
Tags: 2:3.4.6~dfsg-1ubuntu2
* SECURITY UPDATE: permission bypass via incorrect CAP_DAC_OVERRIDE
  handling.
  - debian/patches/security-CVE-2010-0728.patch: fix capability handling
    in source3/{include/smb.h,lib/system.c,smbd/server.c}.
  - CVE-2010-0728
* Removed patches:
  - debian/patches/debian-changes-2:3.4.5~dfsg-2ubuntu2: merge error
  - debian/patches/debian-changes-2:3.4.6~dfsg-1ubuntu1: merge error

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
   Unix SMB/CIFS implementation.
 
3
   Main SMB server routines
 
4
   Copyright (C) Andrew Tridgell                1992-1998
 
5
   Copyright (C) Martin Pool                    2002
 
6
   Copyright (C) Jelmer Vernooij                2002-2003
 
7
   Copyright (C) Volker Lendecke                1993-2007
 
8
   Copyright (C) Jeremy Allison                 1993-2007
 
9
 
 
10
   This program is free software; you can redistribute it and/or modify
 
11
   it under the terms of the GNU General Public License as published by
 
12
   the Free Software Foundation; either version 3 of the License, or
 
13
   (at your option) any later version.
 
14
 
 
15
   This program is distributed in the hope that it will be useful,
 
16
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
17
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
18
   GNU General Public License for more details.
 
19
 
 
20
   You should have received a copy of the GNU General Public License
 
21
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
22
*/
 
23
 
 
24
#include "includes.h"
 
25
#include "smbd/globals.h"
 
26
 
 
27
static_decl_rpc;
 
28
 
 
29
#ifdef WITH_DFS
 
30
extern int dcelogin_atmost_once;
 
31
#endif /* WITH_DFS */
 
32
 
 
33
int smbd_server_fd(void)
 
34
{
 
35
        return server_fd;
 
36
}
 
37
 
 
38
static void smbd_set_server_fd(int fd)
 
39
{
 
40
        server_fd = fd;
 
41
}
 
42
 
 
43
int get_client_fd(void)
 
44
{
 
45
        return server_fd;
 
46
}
 
47
 
 
48
struct event_context *smbd_event_context(void)
 
49
{
 
50
        if (!smbd_event_ctx) {
 
51
                smbd_event_ctx = event_context_init(talloc_autofree_context());
 
52
        }
 
53
        if (!smbd_event_ctx) {
 
54
                smb_panic("Could not init smbd event context");
 
55
        }
 
56
        return smbd_event_ctx;
 
57
}
 
58
 
 
59
struct messaging_context *smbd_messaging_context(void)
 
60
{
 
61
        if (smbd_msg_ctx == NULL) {
 
62
                smbd_msg_ctx = messaging_init(talloc_autofree_context(),
 
63
                                              server_id_self(),
 
64
                                              smbd_event_context());
 
65
        }
 
66
        if (smbd_msg_ctx == NULL) {
 
67
                DEBUG(0, ("Could not init smbd messaging context.\n"));
 
68
        }
 
69
        return smbd_msg_ctx;
 
70
}
 
71
 
 
72
struct memcache *smbd_memcache(void)
 
73
{
 
74
        if (!smbd_memcache_ctx) {
 
75
                smbd_memcache_ctx = memcache_init(talloc_autofree_context(),
 
76
                                                  lp_max_stat_cache_size()*1024);
 
77
        }
 
78
        if (!smbd_memcache_ctx) {
 
79
                smb_panic("Could not init smbd memcache");
 
80
        }
 
81
 
 
82
        return smbd_memcache_ctx;
 
83
}
 
84
 
 
85
/*******************************************************************
 
86
 What to do when smb.conf is updated.
 
87
 ********************************************************************/
 
88
 
 
89
static void smb_conf_updated(struct messaging_context *msg,
 
90
                             void *private_data,
 
91
                             uint32_t msg_type,
 
92
                             struct server_id server_id,
 
93
                             DATA_BLOB *data)
 
94
{
 
95
        DEBUG(10,("smb_conf_updated: Got message saying smb.conf was "
 
96
                  "updated. Reloading.\n"));
 
97
        change_to_root_user();
 
98
        reload_services(False);
 
99
}
 
100
 
 
101
 
 
102
/*******************************************************************
 
103
 Delete a statcache entry.
 
104
 ********************************************************************/
 
105
 
 
106
static void smb_stat_cache_delete(struct messaging_context *msg,
 
107
                                  void *private_data,
 
108
                                  uint32_t msg_tnype,
 
109
                                  struct server_id server_id,
 
110
                                  DATA_BLOB *data)
 
111
{
 
112
        const char *name = (const char *)data->data;
 
113
        DEBUG(10,("smb_stat_cache_delete: delete name %s\n", name));
 
114
        stat_cache_delete(name);
 
115
}
 
116
 
 
117
/****************************************************************************
 
118
  Send a SIGTERM to our process group.
 
119
*****************************************************************************/
 
120
 
 
121
static void  killkids(void)
 
122
{
 
123
        if(am_parent) kill(0,SIGTERM);
 
124
}
 
125
 
 
126
/****************************************************************************
 
127
 Process a sam sync message - not sure whether to do this here or
 
128
 somewhere else.
 
129
****************************************************************************/
 
130
 
 
131
static void msg_sam_sync(struct messaging_context *msg,
 
132
                         void *private_data,
 
133
                         uint32_t msg_type,
 
134
                         struct server_id server_id,
 
135
                         DATA_BLOB *data)
 
136
{
 
137
        DEBUG(10, ("** sam sync message received, ignoring\n"));
 
138
}
 
139
 
 
140
static void msg_exit_server(struct messaging_context *msg,
 
141
                            void *private_data,
 
142
                            uint32_t msg_type,
 
143
                            struct server_id server_id,
 
144
                            DATA_BLOB *data)
 
145
{
 
146
        DEBUG(3, ("got a SHUTDOWN message\n"));
 
147
        exit_server_cleanly(NULL);
 
148
}
 
149
 
 
150
#ifdef DEVELOPER
 
151
static void msg_inject_fault(struct messaging_context *msg,
 
152
                             void *private_data,
 
153
                             uint32_t msg_type,
 
154
                             struct server_id src,
 
155
                             DATA_BLOB *data)
 
156
{
 
157
        int sig;
 
158
 
 
159
        if (data->length != sizeof(sig)) {
 
160
                
 
161
                DEBUG(0, ("Process %s sent bogus signal injection request\n",
 
162
                          procid_str_static(&src)));
 
163
                return;
 
164
        }
 
165
 
 
166
        sig = *(int *)data->data;
 
167
        if (sig == -1) {
 
168
                exit_server("internal error injected");
 
169
                return;
 
170
        }
 
171
 
 
172
#if HAVE_STRSIGNAL
 
173
        DEBUG(0, ("Process %s requested injection of signal %d (%s)\n",
 
174
                  procid_str_static(&src), sig, strsignal(sig)));
 
175
#else
 
176
        DEBUG(0, ("Process %s requested injection of signal %d\n",
 
177
                  procid_str_static(&src), sig));
 
178
#endif
 
179
 
 
180
        kill(sys_getpid(), sig);
 
181
}
 
182
#endif /* DEVELOPER */
 
183
 
 
184
struct child_pid {
 
185
        struct child_pid *prev, *next;
 
186
        pid_t pid;
 
187
};
 
188
 
 
189
static void add_child_pid(pid_t pid)
 
190
{
 
191
        struct child_pid *child;
 
192
 
 
193
        if (lp_max_smbd_processes() == 0) {
 
194
                /* Don't bother with the child list if we don't care anyway */
 
195
                return;
 
196
        }
 
197
 
 
198
        child = SMB_MALLOC_P(struct child_pid);
 
199
        if (child == NULL) {
 
200
                DEBUG(0, ("Could not add child struct -- malloc failed\n"));
 
201
                return;
 
202
        }
 
203
        child->pid = pid;
 
204
        DLIST_ADD(children, child);
 
205
        num_children += 1;
 
206
}
 
207
 
 
208
static void remove_child_pid(pid_t pid, bool unclean_shutdown)
 
209
{
 
210
        struct child_pid *child;
 
211
 
 
212
        if (unclean_shutdown) {
 
213
                /* a child terminated uncleanly so tickle all processes to see 
 
214
                   if they can grab any of the pending locks
 
215
                */
 
216
                DEBUG(3,(__location__ " Unclean shutdown of pid %u\n", (unsigned int)pid));
 
217
                messaging_send_buf(smbd_messaging_context(), procid_self(), 
 
218
                                   MSG_SMB_BRL_VALIDATE, NULL, 0);
 
219
                message_send_all(smbd_messaging_context(), 
 
220
                                 MSG_SMB_UNLOCK, NULL, 0, NULL);
 
221
        }
 
222
 
 
223
        if (lp_max_smbd_processes() == 0) {
 
224
                /* Don't bother with the child list if we don't care anyway */
 
225
                return;
 
226
        }
 
227
 
 
228
        for (child = children; child != NULL; child = child->next) {
 
229
                if (child->pid == pid) {
 
230
                        struct child_pid *tmp = child;
 
231
                        DLIST_REMOVE(children, child);
 
232
                        SAFE_FREE(tmp);
 
233
                        num_children -= 1;
 
234
                        return;
 
235
                }
 
236
        }
 
237
 
 
238
        DEBUG(0, ("Could not find child %d -- ignoring\n", (int)pid));
 
239
}
 
240
 
 
241
/****************************************************************************
 
242
 Have we reached the process limit ?
 
243
****************************************************************************/
 
244
 
 
245
static bool allowable_number_of_smbd_processes(void)
 
246
{
 
247
        int max_processes = lp_max_smbd_processes();
 
248
 
 
249
        if (!max_processes)
 
250
                return True;
 
251
 
 
252
        return num_children < max_processes;
 
253
}
 
254
 
 
255
static void smbd_sig_chld_handler(struct tevent_context *ev,
 
256
                                  struct tevent_signal *se,
 
257
                                  int signum,
 
258
                                  int count,
 
259
                                  void *siginfo,
 
260
                                  void *private_data)
 
261
{
 
262
        pid_t pid;
 
263
        int status;
 
264
 
 
265
        while ((pid = sys_waitpid(-1, &status, WNOHANG)) > 0) {
 
266
                bool unclean_shutdown = False;
 
267
 
 
268
                /* If the child terminated normally, assume
 
269
                   it was an unclean shutdown unless the
 
270
                   status is 0
 
271
                */
 
272
                if (WIFEXITED(status)) {
 
273
                        unclean_shutdown = WEXITSTATUS(status);
 
274
                }
 
275
                /* If the child terminated due to a signal
 
276
                   we always assume it was unclean.
 
277
                */
 
278
                if (WIFSIGNALED(status)) {
 
279
                        unclean_shutdown = True;
 
280
                }
 
281
                remove_child_pid(pid, unclean_shutdown);
 
282
        }
 
283
}
 
284
 
 
285
static void smbd_setup_sig_chld_handler(void)
 
286
{
 
287
        struct tevent_signal *se;
 
288
 
 
289
        se = tevent_add_signal(smbd_event_context(),
 
290
                               smbd_event_context(),
 
291
                               SIGCHLD, 0,
 
292
                               smbd_sig_chld_handler,
 
293
                               NULL);
 
294
        if (!se) {
 
295
                exit_server("failed to setup SIGCHLD handler");
 
296
        }
 
297
}
 
298
 
 
299
struct smbd_open_socket;
 
300
 
 
301
struct smbd_parent_context {
 
302
        bool interactive;
 
303
 
 
304
        /* the list of listening sockets */
 
305
        struct smbd_open_socket *sockets;
 
306
};
 
307
 
 
308
struct smbd_open_socket {
 
309
        struct smbd_open_socket *prev, *next;
 
310
        struct smbd_parent_context *parent;
 
311
        int fd;
 
312
        struct tevent_fd *fde;
 
313
};
 
314
 
 
315
static void smbd_open_socket_close_fn(struct tevent_context *ev,
 
316
                                      struct tevent_fd *fde,
 
317
                                      int fd,
 
318
                                      void *private_data)
 
319
{
 
320
        /* this might be the socket_wrapper swrap_close() */
 
321
        close(fd);
 
322
}
 
323
 
 
324
static void smbd_accept_connection(struct tevent_context *ev,
 
325
                                   struct tevent_fd *fde,
 
326
                                   uint16_t flags,
 
327
                                   void *private_data)
 
328
{
 
329
        struct smbd_open_socket *s = talloc_get_type_abort(private_data,
 
330
                                     struct smbd_open_socket);
 
331
        struct sockaddr_storage addr;
 
332
        socklen_t in_addrlen = sizeof(addr);
 
333
        pid_t pid = 0;
 
334
 
 
335
        smbd_set_server_fd(accept(s->fd,(struct sockaddr *)&addr,&in_addrlen));
 
336
 
 
337
        if (smbd_server_fd() == -1 && errno == EINTR)
 
338
                return;
 
339
 
 
340
        if (smbd_server_fd() == -1) {
 
341
                DEBUG(0,("open_sockets_smbd: accept: %s\n",
 
342
                         strerror(errno)));
 
343
                return;
 
344
        }
 
345
 
 
346
        if (s->parent->interactive) {
 
347
                smbd_process();
 
348
                exit_server_cleanly("end of interactive mode");
 
349
                return;
 
350
        }
 
351
 
 
352
        if (!allowable_number_of_smbd_processes()) {
 
353
                close(smbd_server_fd());
 
354
                smbd_set_server_fd(-1);
 
355
                return;
 
356
        }
 
357
 
 
358
        pid = sys_fork();
 
359
        if (pid == 0) {
 
360
                NTSTATUS status = NT_STATUS_OK;
 
361
                /* Child code ... */
 
362
                am_parent = 0;
 
363
 
 
364
                /* Stop zombies, the parent explicitly handles
 
365
                 * them, counting worker smbds. */
 
366
                CatchChild();
 
367
 
 
368
                /* close our standard file
 
369
                   descriptors */
 
370
                close_low_fds(False);
 
371
 
 
372
                /*
 
373
                 * Can't use TALLOC_FREE here. Nulling out the argument to it
 
374
                 * would overwrite memory we've just freed.
 
375
                 */
 
376
                talloc_free(s->parent);
 
377
                s = NULL;
 
378
 
 
379
                status = reinit_after_fork(smbd_messaging_context(),
 
380
                                           smbd_event_context(), true);
 
381
                if (!NT_STATUS_IS_OK(status)) {
 
382
                        if (NT_STATUS_EQUAL(status,
 
383
                                            NT_STATUS_TOO_MANY_OPENED_FILES)) {
 
384
                                DEBUG(0,("child process cannot initialize "
 
385
                                         "because too many files are open\n"));
 
386
                                goto exit;
 
387
                        }
 
388
                        DEBUG(0,("reinit_after_fork() failed\n"));
 
389
                        smb_panic("reinit_after_fork() failed");
 
390
                }
 
391
 
 
392
                smbd_setup_sig_term_handler();
 
393
                smbd_setup_sig_hup_handler();
 
394
 
 
395
                smbd_process();
 
396
         exit:
 
397
                exit_server_cleanly("end of child");
 
398
                return;
 
399
        } else if (pid < 0) {
 
400
                DEBUG(0,("smbd_accept_connection: sys_fork() failed: %s\n",
 
401
                         strerror(errno)));
 
402
        }
 
403
 
 
404
        /* The parent doesn't need this socket */
 
405
        close(smbd_server_fd());
 
406
 
 
407
        /* Sun May 6 18:56:14 2001 ackley@cs.unm.edu:
 
408
                Clear the closed fd info out of server_fd --
 
409
                and more importantly, out of client_fd in
 
410
                util_sock.c, to avoid a possible
 
411
                getpeername failure if we reopen the logs
 
412
                and use %I in the filename.
 
413
        */
 
414
 
 
415
        smbd_set_server_fd(-1);
 
416
 
 
417
        if (pid != 0) {
 
418
                add_child_pid(pid);
 
419
        }
 
420
 
 
421
        /* Force parent to check log size after
 
422
         * spawning child.  Fix from
 
423
         * klausr@ITAP.Physik.Uni-Stuttgart.De.  The
 
424
         * parent smbd will log to logserver.smb.  It
 
425
         * writes only two messages for each child
 
426
         * started/finished. But each child writes,
 
427
         * say, 50 messages also in logserver.smb,
 
428
         * begining with the debug_count of the
 
429
         * parent, before the child opens its own log
 
430
         * file logserver.client. In a worst case
 
431
         * scenario the size of logserver.smb would be
 
432
         * checked after about 50*50=2500 messages
 
433
         * (ca. 100kb).
 
434
         * */
 
435
        force_check_log_size();
 
436
}
 
437
 
 
438
static bool smbd_open_one_socket(struct smbd_parent_context *parent,
 
439
                                 const struct sockaddr_storage *ifss,
 
440
                                 uint16_t port)
 
441
{
 
442
        struct smbd_open_socket *s;
 
443
 
 
444
        s = talloc(parent, struct smbd_open_socket);
 
445
        if (!s) {
 
446
                return false;
 
447
        }
 
448
 
 
449
        s->parent = parent;
 
450
        s->fd = open_socket_in(SOCK_STREAM,
 
451
                               port,
 
452
                               parent->sockets == NULL ? 0 : 2,
 
453
                               ifss,
 
454
                               true);
 
455
        if (s->fd == -1) {
 
456
                DEBUG(0,("smbd_open_once_socket: open_socket_in: "
 
457
                        "%s\n", strerror(errno)));
 
458
                TALLOC_FREE(s);
 
459
                /*
 
460
                 * We ignore an error here, as we've done before
 
461
                 */
 
462
                return true;
 
463
        }
 
464
 
 
465
        /* ready to listen */
 
466
        set_socket_options(s->fd, "SO_KEEPALIVE");
 
467
        set_socket_options(s->fd, lp_socket_options());
 
468
 
 
469
        /* Set server socket to
 
470
         * non-blocking for the accept. */
 
471
        set_blocking(s->fd, False);
 
472
 
 
473
        if (listen(s->fd, SMBD_LISTEN_BACKLOG) == -1) {
 
474
                DEBUG(0,("open_sockets_smbd: listen: "
 
475
                        "%s\n", strerror(errno)));
 
476
                        close(s->fd);
 
477
                TALLOC_FREE(s);
 
478
                return false;
 
479
        }
 
480
 
 
481
        s->fde = tevent_add_fd(smbd_event_context(),
 
482
                               s,
 
483
                               s->fd, TEVENT_FD_READ,
 
484
                               smbd_accept_connection,
 
485
                               s);
 
486
        if (!s->fde) {
 
487
                DEBUG(0,("open_sockets_smbd: "
 
488
                         "tevent_add_fd: %s\n",
 
489
                         strerror(errno)));
 
490
                close(s->fd);
 
491
                TALLOC_FREE(s);
 
492
                return false;
 
493
        }
 
494
        tevent_fd_set_close_fn(s->fde, smbd_open_socket_close_fn);
 
495
 
 
496
        DLIST_ADD_END(parent->sockets, s, struct smbd_open_socket *);
 
497
 
 
498
        return true;
 
499
}
 
500
 
 
501
/****************************************************************************
 
502
 Open the socket communication.
 
503
****************************************************************************/
 
504
 
 
505
static bool open_sockets_smbd(struct smbd_parent_context *parent,
 
506
                              const char *smb_ports)
 
507
{
 
508
        int num_interfaces = iface_count();
 
509
        int i;
 
510
        char *ports;
 
511
        unsigned dns_port = 0;
 
512
 
 
513
#ifdef HAVE_ATEXIT
 
514
        atexit(killkids);
 
515
#endif
 
516
 
 
517
        /* Stop zombies */
 
518
        smbd_setup_sig_chld_handler();
 
519
 
 
520
        /* use a reasonable default set of ports - listing on 445 and 139 */
 
521
        if (!smb_ports) {
 
522
                ports = lp_smb_ports();
 
523
                if (!ports || !*ports) {
 
524
                        ports = talloc_strdup(talloc_tos(), SMB_PORTS);
 
525
                } else {
 
526
                        ports = talloc_strdup(talloc_tos(), ports);
 
527
                }
 
528
        } else {
 
529
                ports = talloc_strdup(talloc_tos(), smb_ports);
 
530
        }
 
531
 
 
532
        if (lp_interfaces() && lp_bind_interfaces_only()) {
 
533
                /* We have been given an interfaces line, and been
 
534
                   told to only bind to those interfaces. Create a
 
535
                   socket per interface and bind to only these.
 
536
                */
 
537
 
 
538
                /* Now open a listen socket for each of the
 
539
                   interfaces. */
 
540
                for(i = 0; i < num_interfaces; i++) {
 
541
                        const struct sockaddr_storage *ifss =
 
542
                                        iface_n_sockaddr_storage(i);
 
543
                        char *tok;
 
544
                        const char *ptr;
 
545
 
 
546
                        if (ifss == NULL) {
 
547
                                DEBUG(0,("open_sockets_smbd: "
 
548
                                        "interface %d has NULL IP address !\n",
 
549
                                        i));
 
550
                                continue;
 
551
                        }
 
552
 
 
553
                        for (ptr=ports;
 
554
                             next_token_talloc(talloc_tos(),&ptr, &tok, " \t,");) {
 
555
                                unsigned port = atoi(tok);
 
556
                                if (port == 0 || port > 0xffff) {
 
557
                                        continue;
 
558
                                }
 
559
 
 
560
                                if (!smbd_open_one_socket(parent, ifss, port)) {
 
561
                                        return false;
 
562
                                }
 
563
                        }
 
564
                }
 
565
        } else {
 
566
                /* Just bind to 0.0.0.0 - accept connections
 
567
                   from anywhere. */
 
568
 
 
569
                char *tok;
 
570
                const char *ptr;
 
571
                const char *sock_addr = lp_socket_address();
 
572
                char *sock_tok;
 
573
                const char *sock_ptr;
 
574
 
 
575
                if (strequal(sock_addr, "0.0.0.0") ||
 
576
                    strequal(sock_addr, "::")) {
 
577
#if HAVE_IPV6
 
578
                        sock_addr = "::,0.0.0.0";
 
579
#else
 
580
                        sock_addr = "0.0.0.0";
 
581
#endif
 
582
                }
 
583
 
 
584
                for (sock_ptr=sock_addr;
 
585
                     next_token_talloc(talloc_tos(), &sock_ptr, &sock_tok, " \t,"); ) {
 
586
                        for (ptr=ports; next_token_talloc(talloc_tos(), &ptr, &tok, " \t,"); ) {
 
587
                                struct sockaddr_storage ss;
 
588
 
 
589
                                unsigned port = atoi(tok);
 
590
                                if (port == 0 || port > 0xffff) {
 
591
                                        continue;
 
592
                                }
 
593
 
 
594
                                /* Keep the first port for mDNS service
 
595
                                 * registration.
 
596
                                 */
 
597
                                if (dns_port == 0) {
 
598
                                        dns_port = port;
 
599
                                }
 
600
 
 
601
                                /* open an incoming socket */
 
602
                                if (!interpret_string_addr(&ss, sock_tok,
 
603
                                                AI_NUMERICHOST|AI_PASSIVE)) {
 
604
                                        continue;
 
605
                                }
 
606
 
 
607
                                if (!smbd_open_one_socket(parent, &ss, port)) {
 
608
                                        return false;
 
609
                                }
 
610
                        }
 
611
                }
 
612
        }
 
613
 
 
614
        if (parent->sockets == NULL) {
 
615
                DEBUG(0,("open_sockets_smbd: No "
 
616
                        "sockets available to bind to.\n"));
 
617
                return false;
 
618
        }
 
619
 
 
620
        /* Setup the main smbd so that we can get messages. Note that
 
621
           do this after starting listening. This is needed as when in
 
622
           clustered mode, ctdb won't allow us to start doing database
 
623
           operations until it has gone thru a full startup, which
 
624
           includes checking to see that smbd is listening. */
 
625
        claim_connection(NULL,"",
 
626
                         FLAG_MSG_GENERAL|FLAG_MSG_SMBD|FLAG_MSG_DBWRAP);
 
627
 
 
628
        /* Listen to messages */
 
629
 
 
630
        messaging_register(smbd_messaging_context(), NULL,
 
631
                           MSG_SMB_SAM_SYNC, msg_sam_sync);
 
632
        messaging_register(smbd_messaging_context(), NULL,
 
633
                           MSG_SHUTDOWN, msg_exit_server);
 
634
        messaging_register(smbd_messaging_context(), NULL,
 
635
                           MSG_SMB_FILE_RENAME, msg_file_was_renamed);
 
636
        messaging_register(smbd_messaging_context(), NULL,
 
637
                           MSG_SMB_CONF_UPDATED, smb_conf_updated);
 
638
        messaging_register(smbd_messaging_context(), NULL,
 
639
                           MSG_SMB_STAT_CACHE_DELETE, smb_stat_cache_delete);
 
640
        brl_register_msgs(smbd_messaging_context());
 
641
 
 
642
#ifdef CLUSTER_SUPPORT
 
643
        if (lp_clustering()) {
 
644
                ctdbd_register_reconfigure(messaging_ctdbd_connection());
 
645
        }
 
646
#endif
 
647
 
 
648
#ifdef DEVELOPER
 
649
        messaging_register(smbd_messaging_context(), NULL,
 
650
                           MSG_SMB_INJECT_FAULT, msg_inject_fault);
 
651
#endif
 
652
 
 
653
        if (dns_port != 0) {
 
654
#ifdef WITH_DNSSD_SUPPORT
 
655
                smbd_setup_mdns_registration(smbd_event_context(),
 
656
                                             parent, dns_port);
 
657
#endif
 
658
#ifdef WITH_AVAHI_SUPPORT
 
659
                void *avahi_conn;
 
660
 
 
661
                avahi_conn = avahi_start_register(
 
662
                        smbd_event_context(), smbd_event_context(), dns_port);
 
663
                if (avahi_conn == NULL) {
 
664
                        DEBUG(10, ("avahi_start_register failed\n"));
 
665
                }
 
666
#endif
 
667
        }
 
668
 
 
669
        return true;
 
670
}
 
671
 
 
672
static void smbd_parent_loop(struct smbd_parent_context *parent)
 
673
{
 
674
        /* now accept incoming connections - forking a new process
 
675
           for each incoming connection */
 
676
        DEBUG(2,("waiting for connections\n"));
 
677
        while (1) {
 
678
                int ret;
 
679
                TALLOC_CTX *frame = talloc_stackframe();
 
680
 
 
681
                ret = tevent_loop_once(smbd_event_context());
 
682
                if (ret != 0) {
 
683
                        exit_server_cleanly("tevent_loop_once() error");
 
684
                }
 
685
 
 
686
                TALLOC_FREE(frame);
 
687
        } /* end while 1 */
 
688
 
 
689
/* NOTREACHED   return True; */
 
690
}
 
691
 
 
692
/****************************************************************************
 
693
 Reload printers
 
694
**************************************************************************/
 
695
void reload_printers(void)
 
696
{
 
697
        int snum;
 
698
        int n_services = lp_numservices();
 
699
        int pnum = lp_servicenumber(PRINTERS_NAME);
 
700
        const char *pname;
 
701
 
 
702
        if (!lp_load_printers()
 
703
            && (lp_auto_services() == NULL || !strcmp(lp_auto_services(),"")))
 
704
                return;
 
705
 
 
706
        pcap_cache_reload();
 
707
 
 
708
        /* remove stale printers */
 
709
        for (snum = 0; snum < n_services; snum++) {
 
710
                /* avoid removing PRINTERS_NAME or non-autoloaded printers */
 
711
                if (snum == pnum || !(lp_snum_ok(snum) && lp_print_ok(snum) &&
 
712
                                      lp_autoloaded(snum)))
 
713
                        continue;
 
714
 
 
715
                pname = lp_printername(snum);
 
716
                if (!pcap_printername_ok(pname)) {
 
717
                        DEBUG(3, ("removing stale printer %s\n", pname));
 
718
 
 
719
                        if (is_printer_published(NULL, snum, NULL))
 
720
                                nt_printer_publish(NULL, snum, DSPRINT_UNPUBLISH);
 
721
                        del_a_printer(pname);
 
722
                        lp_killservice(snum);
 
723
                }
 
724
        }
 
725
 
 
726
        load_printers();
 
727
}
 
728
 
 
729
/****************************************************************************
 
730
 Reload the services file.
 
731
**************************************************************************/
 
732
 
 
733
bool reload_services(bool test)
 
734
{
 
735
        bool ret;
 
736
 
 
737
        if (lp_loaded()) {
 
738
                char *fname = lp_configfile();
 
739
                if (file_exist(fname) &&
 
740
                    !strcsequal(fname, get_dyn_CONFIGFILE())) {
 
741
                        set_dyn_CONFIGFILE(fname);
 
742
                        test = False;
 
743
                }
 
744
        }
 
745
 
 
746
        reopen_logs();
 
747
 
 
748
        if (test && !lp_file_list_changed())
 
749
                return(True);
 
750
 
 
751
        lp_killunused(conn_snum_used);
 
752
 
 
753
        ret = lp_load(get_dyn_CONFIGFILE(), False, False, True, True);
 
754
 
 
755
        reload_printers();
 
756
 
 
757
        /* perhaps the config filename is now set */
 
758
        if (!test)
 
759
                reload_services(True);
 
760
 
 
761
        reopen_logs();
 
762
 
 
763
        load_interfaces();
 
764
 
 
765
        if (smbd_server_fd() != -1) {
 
766
                set_socket_options(smbd_server_fd(),"SO_KEEPALIVE");
 
767
                set_socket_options(smbd_server_fd(), lp_socket_options());
 
768
        }
 
769
 
 
770
        mangle_reset_cache();
 
771
        reset_stat_cache();
 
772
 
 
773
        /* this forces service parameters to be flushed */
 
774
        set_current_service(NULL,0,True);
 
775
 
 
776
        return(ret);
 
777
}
 
778
 
 
779
/****************************************************************************
 
780
 Exit the server.
 
781
****************************************************************************/
 
782
 
 
783
/* Reasons for shutting down a server process. */
 
784
enum server_exit_reason { SERVER_EXIT_NORMAL, SERVER_EXIT_ABNORMAL };
 
785
 
 
786
static void exit_server_common(enum server_exit_reason how,
 
787
        const char *const reason) _NORETURN_;
 
788
 
 
789
static void exit_server_common(enum server_exit_reason how,
 
790
        const char *const reason)
 
791
{
 
792
        bool had_open_conn;
 
793
 
 
794
        if (!exit_firsttime)
 
795
                exit(0);
 
796
        exit_firsttime = false;
 
797
 
 
798
        change_to_root_user();
 
799
 
 
800
        if (negprot_global_auth_context) {
 
801
                (negprot_global_auth_context->free)(&negprot_global_auth_context);
 
802
        }
 
803
 
 
804
        had_open_conn = conn_close_all();
 
805
 
 
806
        invalidate_all_vuids();
 
807
 
 
808
        /* 3 second timeout. */
 
809
        print_notify_send_messages(smbd_messaging_context(), 3);
 
810
 
 
811
        /* delete our entry in the connections database. */
 
812
        yield_connection(NULL,"");
 
813
 
 
814
#ifdef WITH_DFS
 
815
        if (dcelogin_atmost_once) {
 
816
                dfs_unlogin();
 
817
        }
 
818
#endif
 
819
 
 
820
#ifdef USE_DMAPI
 
821
        /* Destroy Samba DMAPI session only if we are master smbd process */
 
822
        if (am_parent) {
 
823
                if (!dmapi_destroy_session()) {
 
824
                        DEBUG(0,("Unable to close Samba DMAPI session\n"));
 
825
                }
 
826
        }
 
827
#endif
 
828
 
 
829
        locking_end();
 
830
        printing_end();
 
831
 
 
832
        if (how != SERVER_EXIT_NORMAL) {
 
833
                int oldlevel = DEBUGLEVEL;
 
834
 
 
835
                DEBUGLEVEL = 10;
 
836
 
 
837
                DEBUGSEP(0);
 
838
                DEBUG(0,("Abnormal server exit: %s\n",
 
839
                        reason ? reason : "no explanation provided"));
 
840
                DEBUGSEP(0);
 
841
 
 
842
                log_stack_trace();
 
843
 
 
844
                DEBUGLEVEL = oldlevel;
 
845
                dump_core();
 
846
 
 
847
        } else {    
 
848
                DEBUG(3,("Server exit (%s)\n",
 
849
                        (reason ? reason : "normal exit")));
 
850
                if (am_parent) {
 
851
                        pidfile_unlink();
 
852
                }
 
853
        }
 
854
 
 
855
        /* if we had any open SMB connections when we exited then we
 
856
           need to tell the parent smbd so that it can trigger a retry
 
857
           of any locks we may have been holding or open files we were
 
858
           blocking */
 
859
        if (had_open_conn) {
 
860
                exit(1);
 
861
        } else {
 
862
                exit(0);
 
863
        }
 
864
}
 
865
 
 
866
void exit_server(const char *const explanation)
 
867
{
 
868
        exit_server_common(SERVER_EXIT_ABNORMAL, explanation);
 
869
}
 
870
 
 
871
void exit_server_cleanly(const char *const explanation)
 
872
{
 
873
        exit_server_common(SERVER_EXIT_NORMAL, explanation);
 
874
}
 
875
 
 
876
void exit_server_fault(void)
 
877
{
 
878
        exit_server("critical server fault");
 
879
}
 
880
 
 
881
/****************************************************************************
 
882
 Initialise connect, service and file structs.
 
883
****************************************************************************/
 
884
 
 
885
static bool init_structs(void )
 
886
{
 
887
        /*
 
888
         * Set the machine NETBIOS name if not already
 
889
         * set from the config file.
 
890
         */
 
891
 
 
892
        if (!init_names())
 
893
                return False;
 
894
 
 
895
        conn_init();
 
896
 
 
897
        file_init();
 
898
 
 
899
        init_dptrs();
 
900
 
 
901
        if (!secrets_init())
 
902
                return False;
 
903
 
 
904
        return True;
 
905
}
 
906
 
 
907
/****************************************************************************
 
908
 main program.
 
909
****************************************************************************/
 
910
 
 
911
/* Declare prototype for build_options() to avoid having to run it through
 
912
   mkproto.h.  Mixing $(builddir) and $(srcdir) source files in the current
 
913
   prototype generation system is too complicated. */
 
914
 
 
915
extern void build_options(bool screen);
 
916
 
 
917
 int main(int argc,const char *argv[])
 
918
{
 
919
        /* shall I run as a daemon */
 
920
        bool is_daemon = false;
 
921
        bool interactive = false;
 
922
        bool Fork = true;
 
923
        bool no_process_group = false;
 
924
        bool log_stdout = false;
 
925
        char *ports = NULL;
 
926
        char *profile_level = NULL;
 
927
        int opt;
 
928
        poptContext pc;
 
929
        bool print_build_options = False;
 
930
        enum {
 
931
                OPT_DAEMON = 1000,
 
932
                OPT_INTERACTIVE,
 
933
                OPT_FORK,
 
934
                OPT_NO_PROCESS_GROUP,
 
935
                OPT_LOG_STDOUT
 
936
        };
 
937
        struct poptOption long_options[] = {
 
938
        POPT_AUTOHELP
 
939
        {"daemon", 'D', POPT_ARG_NONE, NULL, OPT_DAEMON, "Become a daemon (default)" },
 
940
        {"interactive", 'i', POPT_ARG_NONE, NULL, OPT_INTERACTIVE, "Run interactive (not a daemon)"},
 
941
        {"foreground", 'F', POPT_ARG_NONE, NULL, OPT_FORK, "Run daemon in foreground (for daemontools, etc.)" },
 
942
        {"no-process-group", '\0', POPT_ARG_NONE, NULL, OPT_NO_PROCESS_GROUP, "Don't create a new process group" },
 
943
        {"log-stdout", 'S', POPT_ARG_NONE, NULL, OPT_LOG_STDOUT, "Log to stdout" },
 
944
        {"build-options", 'b', POPT_ARG_NONE, NULL, 'b', "Print build options" },
 
945
        {"port", 'p', POPT_ARG_STRING, &ports, 0, "Listen on the specified ports"},
 
946
        {"profiling-level", 'P', POPT_ARG_STRING, &profile_level, 0, "Set profiling level","PROFILE_LEVEL"},
 
947
        POPT_COMMON_SAMBA
 
948
        POPT_COMMON_DYNCONFIG
 
949
        POPT_TABLEEND
 
950
        };
 
951
        struct smbd_parent_context *parent = NULL;
 
952
        TALLOC_CTX *frame = talloc_stackframe(); /* Setup tos. */
 
953
 
 
954
        smbd_init_globals();
 
955
 
 
956
        TimeInit();
 
957
 
 
958
#ifdef HAVE_SET_AUTH_PARAMETERS
 
959
        set_auth_parameters(argc,argv);
 
960
#endif
 
961
 
 
962
        pc = poptGetContext("smbd", argc, argv, long_options, 0);
 
963
        while((opt = poptGetNextOpt(pc)) != -1) {
 
964
                switch (opt)  {
 
965
                case OPT_DAEMON:
 
966
                        is_daemon = true;
 
967
                        break;
 
968
                case OPT_INTERACTIVE:
 
969
                        interactive = true;
 
970
                        break;
 
971
                case OPT_FORK:
 
972
                        Fork = false;
 
973
                        break;
 
974
                case OPT_NO_PROCESS_GROUP:
 
975
                        no_process_group = true;
 
976
                        break;
 
977
                case OPT_LOG_STDOUT:
 
978
                        log_stdout = true;
 
979
                        break;
 
980
                case 'b':
 
981
                        print_build_options = True;
 
982
                        break;
 
983
                default:
 
984
                        d_fprintf(stderr, "\nInvalid option %s: %s\n\n",
 
985
                                  poptBadOption(pc, 0), poptStrerror(opt));
 
986
                        poptPrintUsage(pc, stderr, 0);
 
987
                        exit(1);
 
988
                }
 
989
        }
 
990
        poptFreeContext(pc);
 
991
 
 
992
        if (interactive) {
 
993
                Fork = False;
 
994
                log_stdout = True;
 
995
        }
 
996
 
 
997
        setup_logging(argv[0],log_stdout);
 
998
 
 
999
        if (print_build_options) {
 
1000
                build_options(True); /* Display output to screen as well as debug */
 
1001
                exit(0);
 
1002
        }
 
1003
 
 
1004
        load_case_tables();
 
1005
 
 
1006
#ifdef HAVE_SETLUID
 
1007
        /* needed for SecureWare on SCO */
 
1008
        setluid(0);
 
1009
#endif
 
1010
 
 
1011
        sec_init();
 
1012
 
 
1013
        set_remote_machine_name("smbd", False);
 
1014
 
 
1015
        if (interactive && (DEBUGLEVEL >= 9)) {
 
1016
                talloc_enable_leak_report();
 
1017
        }
 
1018
 
 
1019
        if (log_stdout && Fork) {
 
1020
                DEBUG(0,("ERROR: Can't log to stdout (-S) unless daemon is in foreground (-F) or interactive (-i)\n"));
 
1021
                exit(1);
 
1022
        }
 
1023
 
 
1024
        /* we want to re-seed early to prevent time delays causing
 
1025
           client problems at a later date. (tridge) */
 
1026
        generate_random_buffer(NULL, 0);
 
1027
 
 
1028
        /* make absolutely sure we run as root - to handle cases where people
 
1029
           are crazy enough to have it setuid */
 
1030
 
 
1031
        gain_root_privilege();
 
1032
        gain_root_group_privilege();
 
1033
 
 
1034
        /*
 
1035
         * Ensure we have CAP_KILL capability set on Linux,
 
1036
         * where we need this to communicate with threads.
 
1037
         * This is inherited by new threads, but not by new
 
1038
         * processes across exec().
 
1039
         */
 
1040
        set_effective_capability(KILL_CAPABILITY);
 
1041
 
 
1042
        fault_setup((void (*)(void *))exit_server_fault);
 
1043
        dump_core_setup("smbd");
 
1044
 
 
1045
        /* we are never interested in SIGPIPE */
 
1046
        BlockSignals(True,SIGPIPE);
 
1047
 
 
1048
#if defined(SIGFPE)
 
1049
        /* we are never interested in SIGFPE */
 
1050
        BlockSignals(True,SIGFPE);
 
1051
#endif
 
1052
 
 
1053
#if defined(SIGUSR2)
 
1054
        /* We are no longer interested in USR2 */
 
1055
        BlockSignals(True,SIGUSR2);
 
1056
#endif
 
1057
 
 
1058
        /* POSIX demands that signals are inherited. If the invoking process has
 
1059
         * these signals masked, we will have problems, as we won't recieve them. */
 
1060
        BlockSignals(False, SIGHUP);
 
1061
        BlockSignals(False, SIGUSR1);
 
1062
        BlockSignals(False, SIGTERM);
 
1063
 
 
1064
        /* Ensure we leave no zombies until we
 
1065
         * correctly set up child handling below. */
 
1066
 
 
1067
        CatchChild();
 
1068
 
 
1069
        /* we want total control over the permissions on created files,
 
1070
           so set our umask to 0 */
 
1071
        umask(0);
 
1072
 
 
1073
        init_sec_ctx();
 
1074
 
 
1075
        reopen_logs();
 
1076
 
 
1077
        DEBUG(0,("smbd version %s started.\n", samba_version_string()));
 
1078
        DEBUGADD(0,("%s\n", COPYRIGHT_STARTUP_MESSAGE));
 
1079
 
 
1080
        DEBUG(2,("uid=%d gid=%d euid=%d egid=%d\n",
 
1081
                 (int)getuid(),(int)getgid(),(int)geteuid(),(int)getegid()));
 
1082
 
 
1083
        /* Output the build options to the debug log */ 
 
1084
        build_options(False);
 
1085
 
 
1086
        if (sizeof(uint16) < 2 || sizeof(uint32) < 4) {
 
1087
                DEBUG(0,("ERROR: Samba is not configured correctly for the word size on your machine\n"));
 
1088
                exit(1);
 
1089
        }
 
1090
 
 
1091
        if (!lp_load_initial_only(get_dyn_CONFIGFILE())) {
 
1092
                DEBUG(0, ("error opening config file\n"));
 
1093
                exit(1);
 
1094
        }
 
1095
 
 
1096
        if (smbd_messaging_context() == NULL)
 
1097
                exit(1);
 
1098
 
 
1099
        if (!reload_services(False))
 
1100
                return(-1);     
 
1101
 
 
1102
        init_structs();
 
1103
 
 
1104
#ifdef WITH_PROFILE
 
1105
        if (!profile_setup(smbd_messaging_context(), False)) {
 
1106
                DEBUG(0,("ERROR: failed to setup profiling\n"));
 
1107
                return -1;
 
1108
        }
 
1109
        if (profile_level != NULL) {
 
1110
                int pl = atoi(profile_level);
 
1111
                struct server_id src;
 
1112
 
 
1113
                DEBUG(1, ("setting profiling level: %s\n",profile_level));
 
1114
                src.pid = getpid();
 
1115
                set_profile_level(pl, src);
 
1116
        }
 
1117
#endif
 
1118
 
 
1119
        DEBUG(3,( "loaded services\n"));
 
1120
 
 
1121
        if (!is_daemon && !is_a_socket(0)) {
 
1122
                if (!interactive)
 
1123
                        DEBUG(0,("standard input is not a socket, assuming -D option\n"));
 
1124
 
 
1125
                /*
 
1126
                 * Setting is_daemon here prevents us from eventually calling
 
1127
                 * the open_sockets_inetd()
 
1128
                 */
 
1129
 
 
1130
                is_daemon = True;
 
1131
        }
 
1132
 
 
1133
        if (is_daemon && !interactive) {
 
1134
                DEBUG( 3, ( "Becoming a daemon.\n" ) );
 
1135
                become_daemon(Fork, no_process_group);
 
1136
        }
 
1137
 
 
1138
#if HAVE_SETPGID
 
1139
        /*
 
1140
         * If we're interactive we want to set our own process group for
 
1141
         * signal management.
 
1142
         */
 
1143
        if (interactive && !no_process_group)
 
1144
                setpgid( (pid_t)0, (pid_t)0);
 
1145
#endif
 
1146
 
 
1147
        if (!directory_exist(lp_lockdir()))
 
1148
                mkdir(lp_lockdir(), 0755);
 
1149
 
 
1150
        if (is_daemon)
 
1151
                pidfile_create("smbd");
 
1152
 
 
1153
        if (!NT_STATUS_IS_OK(reinit_after_fork(smbd_messaging_context(),
 
1154
                             smbd_event_context(), false))) {
 
1155
                DEBUG(0,("reinit_after_fork() failed\n"));
 
1156
                exit(1);
 
1157
        }
 
1158
 
 
1159
        smbd_setup_sig_term_handler();
 
1160
        smbd_setup_sig_hup_handler();
 
1161
 
 
1162
        /* Setup all the TDB's - including CLEAR_IF_FIRST tdb's. */
 
1163
 
 
1164
        if (smbd_memcache() == NULL) {
 
1165
                exit(1);
 
1166
        }
 
1167
 
 
1168
        memcache_set_global(smbd_memcache());
 
1169
 
 
1170
        /* Initialise the password backed before the global_sam_sid
 
1171
           to ensure that we fetch from ldap before we make a domain sid up */
 
1172
 
 
1173
        if(!initialize_password_db(False, smbd_event_context()))
 
1174
                exit(1);
 
1175
 
 
1176
        if (!secrets_init()) {
 
1177
                DEBUG(0, ("ERROR: smbd can not open secrets.tdb\n"));
 
1178
                exit(1);
 
1179
        }
 
1180
 
 
1181
        if(!get_global_sam_sid()) {
 
1182
                DEBUG(0,("ERROR: Samba cannot create a SAM SID.\n"));
 
1183
                exit(1);
 
1184
        }
 
1185
 
 
1186
        if (!session_init())
 
1187
                exit(1);
 
1188
 
 
1189
        if (!connections_init(True))
 
1190
                exit(1);
 
1191
 
 
1192
        if (!locking_init())
 
1193
                exit(1);
 
1194
 
 
1195
        namecache_enable();
 
1196
 
 
1197
        if (!W_ERROR_IS_OK(registry_init_full()))
 
1198
                exit(1);
 
1199
 
 
1200
#if 0
 
1201
        if (!init_svcctl_db())
 
1202
                exit(1);
 
1203
#endif
 
1204
 
 
1205
        if (!print_backend_init(smbd_messaging_context()))
 
1206
                exit(1);
 
1207
 
 
1208
        if (!init_guest_info()) {
 
1209
                DEBUG(0,("ERROR: failed to setup guest info.\n"));
 
1210
                return -1;
 
1211
        }
 
1212
 
 
1213
        /* only start the background queue daemon if we are 
 
1214
           running as a daemon -- bad things will happen if
 
1215
           smbd is launched via inetd and we fork a copy of 
 
1216
           ourselves here */
 
1217
 
 
1218
        if (is_daemon && !interactive
 
1219
            && lp_parm_bool(-1, "smbd", "backgroundqueue", true)) {
 
1220
                start_background_queue();
 
1221
        }
 
1222
 
 
1223
        if (!is_daemon) {
 
1224
                /* inetd mode */
 
1225
                TALLOC_FREE(frame);
 
1226
 
 
1227
                /* Started from inetd. fd 0 is the socket. */
 
1228
                /* We will abort gracefully when the client or remote system
 
1229
                   goes away */
 
1230
                smbd_set_server_fd(dup(0));
 
1231
 
 
1232
                /* close our standard file descriptors */
 
1233
                close_low_fds(False); /* Don't close stderr */
 
1234
 
 
1235
#ifdef HAVE_ATEXIT
 
1236
                atexit(killkids);
 
1237
#endif
 
1238
 
 
1239
                /* Stop zombies */
 
1240
                smbd_setup_sig_chld_handler();
 
1241
 
 
1242
                smbd_process();
 
1243
 
 
1244
                exit_server_cleanly(NULL);
 
1245
                return(0);
 
1246
        }
 
1247
 
 
1248
        parent = talloc_zero(smbd_event_context(), struct smbd_parent_context);
 
1249
        if (!parent) {
 
1250
                exit_server("talloc(struct smbd_parent_context) failed");
 
1251
        }
 
1252
        parent->interactive = interactive;
 
1253
 
 
1254
        if (!open_sockets_smbd(parent, ports))
 
1255
                exit_server("open_sockets_smbd() failed");
 
1256
 
 
1257
        TALLOC_FREE(frame);
 
1258
 
 
1259
        smbd_parent_loop(parent);
 
1260
 
 
1261
        exit_server_cleanly(NULL);
 
1262
        return(0);
 
1263
}