~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): Chuck Short
  • Date: 2010-03-19 21:17:40 UTC
  • mfrom: (0.27.11 upstream) (0.34.7 sid)
  • Revision ID: james.westby@ubuntu.com-20100319211740-gicih0sczyw0x1iv
Tags: 2:3.4.7~dfsg-1ubuntu1
* Merge from debian testing.  Remaining changes:
  + debian/patches/VERSION.patch:
    - set SAMBA_VERSION_SUFFIX to Ubuntu.
  + 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 additon to authenticated ones.
    - add map to guest = Bad user, maps bad username to gues access.
  + debian/samba-common.conf:
    - Do not change priority to high if dhclient3 is installed.
    - Use priority medium instead of high for the workgroup question.
  + debian/mksambapasswd.awk:
    - Do not add user with UID less than 1000 to smbpasswd.
  + debian/control:
    - Make libswbclient0 replace/conflict with hardy's likewise-open.
    - Don't build against ctdb, since its not in main yet.
  + debian/rules:
    - Enable "native" PIE hardening.
    - Add BIND_NOW to maximize benefit of RELRO hardening.
  + Add ufw integration:
    - Created debian/samba.ufw.profile.
    - debian/rules, debian/samba.dirs, debian/samba.files: install
  + Add apport hook:
    - Created debian/source_samba.py.
    - debian/rules, debian/samba.dirs, debian/samba-common-bin.files: install
  + debian/control: Recommend keyutils for smbfs (LP: #493565)
  + debian/patches/ubuntu-gecos-fix.patch: Fix gecos parsing backported from Samba 3.5.x (LP: #182572)
  + debian/samba.postinst: Avoid scary pdbedit warnings on first import. (LP: #24741)
  + debian/samba.logrotate: Make it upstart compatible (LP: #529290)
  + debian/samba-common.dhcp: Fix typo to get a proper parsing in /etc/samba/dhcp. (LP: #507374)
  + Dropped:
    debian/patches/debian/patches/security-CVE-2010-0728.patch: Included upstream.

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
 
}