source: trunk/server/source3/smbd/server.c@ 854

Last change on this file since 854 was 845, checked in by Silvan Scherrer, 12 years ago

Samba Server 3.6: fix exceptq crash

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