/* setup our listening sockets on the configured network interfaces */ NTSTATUS nbtd_startup_interfaces(struct nbtd_server *nbtsrv, struct loadparm_context *lp_ctx, struct interface *ifaces) { int num_interfaces = iface_count(ifaces); int i; TALLOC_CTX *tmp_ctx = talloc_new(nbtsrv); NTSTATUS status; /* if we are allowing incoming packets from any address, then we also need to bind to the wildcard address */ if (!lp_bind_interfaces_only(lp_ctx)) { const char *primary_address; /* the primary address is the address we will return for non-WINS queries not made on a specific interface */ if (num_interfaces > 0) { primary_address = iface_n_ip(ifaces, 0); } else { primary_address = inet_ntoa(interpret_addr2( lp_netbios_name(lp_ctx))); } primary_address = talloc_strdup(tmp_ctx, primary_address); NT_STATUS_HAVE_NO_MEMORY(primary_address); status = nbtd_add_socket(nbtsrv, lp_ctx, "0.0.0.0", primary_address, talloc_strdup(tmp_ctx, "255.255.255.255"), talloc_strdup(tmp_ctx, "0.0.0.0")); NT_STATUS_NOT_OK_RETURN(status); } for (i=0; i<num_interfaces; i++) { const char *bcast = iface_n_bcast(ifaces, i); const char *address, *netmask; /* we can't assume every interface is broadcast capable */ if (bcast == NULL) continue; address = talloc_strdup(tmp_ctx, iface_n_ip(ifaces, i)); bcast = talloc_strdup(tmp_ctx, bcast); netmask = talloc_strdup(tmp_ctx, iface_n_netmask(ifaces, i)); status = nbtd_add_socket(nbtsrv, lp_ctx, address, address, bcast, netmask); NT_STATUS_NOT_OK_RETURN(status); } if (lp_wins_server_list(lp_ctx)) { status = nbtd_add_wins_socket(nbtsrv); NT_STATUS_NOT_OK_RETURN(status); } talloc_free(tmp_ctx); return NT_STATUS_OK; }
/* startup the web server task */ static void websrv_task_init(struct task_server *task) { NTSTATUS status; uint16_t port = lp_web_port(task->lp_ctx); const struct model_ops *model_ops; struct web_server_data *wdata; task_server_set_title(task, "task[websrv]"); /* run the web server as a single process */ model_ops = process_model_startup(task->event_ctx, "single"); if (!model_ops) goto failed; if (lp_interfaces(task->lp_ctx) && lp_bind_interfaces_only(task->lp_ctx)) { int num_interfaces; int i; struct interface *ifaces; load_interfaces(NULL, lp_interfaces(task->lp_ctx), &ifaces); num_interfaces = iface_count(ifaces); for(i = 0; i < num_interfaces; i++) { const char *address = iface_n_ip(ifaces, i); status = stream_setup_socket(task->event_ctx, task->lp_ctx, model_ops, &web_stream_ops, "ipv4", address, &port, lp_socket_options(task->lp_ctx), task); if (!NT_STATUS_IS_OK(status)) goto failed; } talloc_free(ifaces); } else { status = stream_setup_socket(task->event_ctx, task->lp_ctx, model_ops, &web_stream_ops, "ipv4", lp_socket_address(task->lp_ctx), &port, lp_socket_options(task->lp_ctx), task); if (!NT_STATUS_IS_OK(status)) goto failed; } /* startup the esp processor - unfortunately we can't do this per connection as that wouldn't allow for session variables */ wdata = talloc_zero(task, struct web_server_data); if (wdata == NULL)goto failed; task->private_data = wdata; wdata->tls_params = tls_initialise(wdata, task->lp_ctx); if (wdata->tls_params == NULL) goto failed; if (!wsgi_initialize(wdata)) goto failed; return; failed: task_server_terminate(task, "websrv_task_init: failed to startup web server task", true); }
static bool epmd_open_sockets(struct tevent_context *ev_ctx, struct messaging_context *msg_ctx) { uint32_t num_ifs = iface_count(); uint16_t port; uint32_t i; if (lp_interfaces() && lp_bind_interfaces_only()) { /* * We have been given an interfaces line, and been told to only * bind to those interfaces. Create a socket per interface and * bind to only these. */ /* Now open a listen socket for each of the interfaces. */ for(i = 0; i < num_ifs; i++) { const struct sockaddr_storage *ifss = iface_n_sockaddr_storage(i); port = setup_dcerpc_ncacn_tcpip_socket(ev_ctx, msg_ctx, ndr_table_epmapper.syntax_id, ifss, 135); if (port == 0) { return false; } } } else { const char *sock_addr = lp_socket_address(); const char *sock_ptr; char *sock_tok; if (strequal(sock_addr, "0.0.0.0") || strequal(sock_addr, "::")) { #if HAVE_IPV6 sock_addr = "::"; #else sock_addr = "0.0.0.0"; #endif } for (sock_ptr = sock_addr; next_token_talloc(talloc_tos(), &sock_ptr, &sock_tok, " \t,"); ) { struct sockaddr_storage ss; /* open an incoming socket */ if (!interpret_string_addr(&ss, sock_tok, AI_NUMERICHOST|AI_PASSIVE)) { continue; } port = setup_dcerpc_ncacn_tcpip_socket(ev_ctx, msg_ctx, ndr_table_epmapper.syntax_id, &ss, 135); if (port == 0) { return false; } } } return true; }
static bool open_sockets_smbd(struct smbd_parent_context *parent, struct tevent_context *ev_ctx, struct messaging_context *msg_ctx, const char *smb_ports) { int num_interfaces = iface_count(); int i; const char *ports; unsigned dns_port = 0; #ifdef HAVE_ATEXIT atexit(killkids); #endif /* Stop zombies */ smbd_setup_sig_chld_handler(ev_ctx); /* use a reasonable default set of ports - listing on 445 and 139 */ if (!smb_ports) { ports = lp_smb_ports(); if (!ports || !*ports) { ports = talloc_strdup(talloc_tos(), SMB_PORTS); } else { ports = talloc_strdup(talloc_tos(), ports); } } else { ports = talloc_strdup(talloc_tos(), smb_ports); } if (lp_interfaces() && lp_bind_interfaces_only()) { /* We have been given an interfaces line, and been told to only bind to those interfaces. Create a socket per interface and bind to only these. */ /* Now open a listen socket for each of the interfaces. */ for(i = 0; i < num_interfaces; i++) { const struct sockaddr_storage *ifss = iface_n_sockaddr_storage(i); char *tok; const char *ptr; if (ifss == NULL) { DEBUG(0,("open_sockets_smbd: " "interface %d has NULL IP address !\n", i)); continue; } for (ptr=ports; next_token_talloc(talloc_tos(),&ptr, &tok, " \t,");) { unsigned port = atoi(tok); if (port == 0 || port > 0xffff) { continue; } /* Keep the first port for mDNS service * registration. */ if (dns_port == 0) { dns_port = port; } if (!smbd_open_one_socket(parent, ev_ctx, msg_ctx, ifss, port)) { return false; } } } } else { /* Just bind to 0.0.0.0 - accept connections from anywhere. */ char *tok; const char *ptr; const char *sock_addr = lp_socket_address(); char *sock_tok; const char *sock_ptr; if (strequal(sock_addr, "0.0.0.0") || strequal(sock_addr, "::")) { #if HAVE_IPV6 sock_addr = "::,0.0.0.0"; #else sock_addr = "0.0.0.0"; #endif } for (sock_ptr=sock_addr; next_token_talloc(talloc_tos(), &sock_ptr, &sock_tok, " \t,"); ) { for (ptr=ports; next_token_talloc(talloc_tos(), &ptr, &tok, " \t,"); ) { struct sockaddr_storage ss; unsigned port = atoi(tok); if (port == 0 || port > 0xffff) { continue; } /* Keep the first port for mDNS service * registration. */ if (dns_port == 0) { dns_port = port; } /* open an incoming socket */ if (!interpret_string_addr(&ss, sock_tok, AI_NUMERICHOST|AI_PASSIVE)) { continue; } if (!smbd_open_one_socket(parent, ev_ctx, msg_ctx, &ss, port)) { return false; } } } } if (parent->sockets == NULL) { DEBUG(0,("open_sockets_smbd: No " "sockets available to bind to.\n")); return false; } /* Setup the main smbd so that we can get messages. Note that do this after starting listening. This is needed as when in clustered mode, ctdb won't allow us to start doing database operations until it has gone thru a full startup, which includes checking to see that smbd is listening. */ if (!serverid_register(procid_self(), FLAG_MSG_GENERAL|FLAG_MSG_SMBD |FLAG_MSG_PRINT_GENERAL |FLAG_MSG_DBWRAP)) { DEBUG(0, ("open_sockets_smbd: Failed to register " "myself in serverid.tdb\n")); return false; } /* Listen to messages */ messaging_register(msg_ctx, NULL, MSG_SMB_SAM_SYNC, msg_sam_sync); messaging_register(msg_ctx, NULL, MSG_SHUTDOWN, msg_exit_server); messaging_register(msg_ctx, NULL, MSG_SMB_FILE_RENAME, msg_file_was_renamed); messaging_register(msg_ctx, ev_ctx, MSG_SMB_CONF_UPDATED, smb_conf_updated); messaging_register(msg_ctx, NULL, MSG_SMB_STAT_CACHE_DELETE, smb_stat_cache_delete); messaging_register(msg_ctx, NULL, MSG_DEBUG, smbd_msg_debug); messaging_register(msg_ctx, ev_ctx, MSG_PRINTER_PCAP, smb_pcap_updated); brl_register_msgs(msg_ctx); msg_idmap_register_msg(msg_ctx); #ifdef CLUSTER_SUPPORT if (lp_clustering()) { ctdbd_register_reconfigure(messaging_ctdbd_connection()); } #endif #ifdef DEVELOPER messaging_register(msg_ctx, NULL, MSG_SMB_INJECT_FAULT, msg_inject_fault); #endif if (lp_multicast_dns_register() && (dns_port != 0)) { #ifdef WITH_DNSSD_SUPPORT smbd_setup_mdns_registration(ev_ctx, parent, dns_port); #endif #ifdef WITH_AVAHI_SUPPORT void *avahi_conn; avahi_conn = avahi_start_register(ev_ctx, ev_ctx, dns_port); if (avahi_conn == NULL) { DEBUG(10, ("avahi_start_register failed\n")); } #endif } return true; }
static bool open_sockets_smbd(struct smbd_parent_context *parent, struct tevent_context *ev_ctx, struct messaging_context *msg_ctx, const char *smb_ports) { int num_interfaces = iface_count(); int i,j; const char **ports; unsigned dns_port = 0; #ifdef HAVE_ATEXIT atexit(killkids); #endif /* Stop zombies */ smbd_setup_sig_chld_handler(parent); ports = lp_smb_ports(); /* use a reasonable default set of ports - listing on 445 and 139 */ if (smb_ports) { char **l; l = str_list_make_v3(talloc_tos(), smb_ports, NULL); ports = discard_const_p(const char *, l); } for (j = 0; ports && ports[j]; j++) { unsigned port = atoi(ports[j]); if (port == 0 || port > 0xffff) { exit_server_cleanly("Invalid port in the config or on " "the commandline specified!"); } } if (lp_interfaces() && lp_bind_interfaces_only()) { /* We have been given an interfaces line, and been told to only bind to those interfaces. Create a socket per interface and bind to only these. */ /* Now open a listen socket for each of the interfaces. */ for(i = 0; i < num_interfaces; i++) { const struct sockaddr_storage *ifss = iface_n_sockaddr_storage(i); if (ifss == NULL) { DEBUG(0,("open_sockets_smbd: " "interface %d has NULL IP address !\n", i)); continue; } for (j = 0; ports && ports[j]; j++) { unsigned port = atoi(ports[j]); /* Keep the first port for mDNS service * registration. */ if (dns_port == 0) { dns_port = port; } if (!smbd_open_one_socket(parent, ev_ctx, ifss, port)) { return false; } } } } else { /* Just bind to 0.0.0.0 - accept connections from anywhere. */ const char *sock_addr; char *sock_tok; const char *sock_ptr; #if HAVE_IPV6 sock_addr = "::,0.0.0.0"; #else sock_addr = "0.0.0.0"; #endif for (sock_ptr=sock_addr; next_token_talloc(talloc_tos(), &sock_ptr, &sock_tok, " \t,"); ) { for (j = 0; ports && ports[j]; j++) { struct sockaddr_storage ss; unsigned port = atoi(ports[j]); /* Keep the first port for mDNS service * registration. */ if (dns_port == 0) { dns_port = port; } /* open an incoming socket */ if (!interpret_string_addr(&ss, sock_tok, AI_NUMERICHOST|AI_PASSIVE)) { continue; } /* * If we fail to open any sockets * in this loop the parent-sockets == NULL * case below will prevent us from starting. */ (void)smbd_open_one_socket(parent, ev_ctx, &ss, port); } } } if (parent->sockets == NULL) { DEBUG(0,("open_sockets_smbd: No " "sockets available to bind to.\n")); return false; } /* Setup the main smbd so that we can get messages. Note that do this after starting listening. This is needed as when in clustered mode, ctdb won't allow us to start doing database operations until it has gone thru a full startup, which includes checking to see that smbd is listening. */ if (!serverid_register(messaging_server_id(msg_ctx), FLAG_MSG_GENERAL|FLAG_MSG_SMBD |FLAG_MSG_PRINT_GENERAL |FLAG_MSG_DBWRAP)) { DEBUG(0, ("open_sockets_smbd: Failed to register " "myself in serverid.tdb\n")); return false; } /* Listen to messages */ messaging_register(msg_ctx, NULL, MSG_SHUTDOWN, msg_exit_server); messaging_register(msg_ctx, ev_ctx, MSG_SMB_CONF_UPDATED, smbd_parent_conf_updated); messaging_register(msg_ctx, NULL, MSG_SMB_STAT_CACHE_DELETE, smb_stat_cache_delete); messaging_register(msg_ctx, NULL, MSG_DEBUG, smbd_msg_debug); messaging_register(msg_ctx, NULL, MSG_SMB_BRL_VALIDATE, brl_revalidate); messaging_register(msg_ctx, NULL, MSG_SMB_FORCE_TDIS, smb_parent_send_to_children); messaging_register(msg_ctx, NULL, MSG_SMB_KILL_CLIENT_IP, smb_parent_send_to_children); messaging_register(msg_ctx, NULL, MSG_SMB_TELL_NUM_CHILDREN, smb_tell_num_children); messaging_register(msg_ctx, NULL, ID_CACHE_DELETE, smbd_parent_id_cache_delete); messaging_register(msg_ctx, NULL, ID_CACHE_KILL, smbd_parent_id_cache_kill); if (lp_clustering()) { struct ctdbd_connection *conn = messaging_ctdbd_connection(); register_with_ctdbd(conn, CTDB_SRVID_RECONFIGURE, smbd_parent_ctdb_reconfigured, msg_ctx); register_with_ctdbd(conn, CTDB_SRVID_SAMBA_NOTIFY, smbd_parent_ctdb_reconfigured, msg_ctx); } #ifdef DEVELOPER messaging_register(msg_ctx, NULL, MSG_SMB_INJECT_FAULT, msg_inject_fault); #endif if (lp_multicast_dns_register() && (dns_port != 0)) { #ifdef WITH_DNSSD_SUPPORT smbd_setup_mdns_registration(ev_ctx, parent, dns_port); #endif #ifdef WITH_AVAHI_SUPPORT void *avahi_conn; avahi_conn = avahi_start_register(ev_ctx, ev_ctx, dns_port); if (avahi_conn == NULL) { DEBUG(10, ("avahi_start_register failed\n")); } #endif } return true; }
/* open the ldap server sockets */ static void ldapsrv_task_init(struct task_server *task) { char *ldapi_path; #ifdef WITH_LDAPI_PRIV_SOCKET char *priv_dir; #endif struct ldapsrv_service *ldap_service; NTSTATUS status; const struct model_ops *model_ops; switch (lp_server_role(task->lp_ctx)) { case ROLE_STANDALONE: task_server_terminate(task, "ldap_server: no LDAP server required in standalone configuration", false); return; case ROLE_DOMAIN_MEMBER: task_server_terminate(task, "ldap_server: no LDAP server required in member server configuration", false); return; case ROLE_DOMAIN_CONTROLLER: /* Yes, we want an LDAP server */ break; } task_server_set_title(task, "task[ldapsrv]"); /* run the ldap server as a single process */ model_ops = process_model_startup(task->event_ctx, "single"); if (!model_ops) goto failed; ldap_service = talloc_zero(task, struct ldapsrv_service); if (ldap_service == NULL) goto failed; ldap_service->task = task; ldap_service->tls_params = tls_initialise(ldap_service, task->lp_ctx); if (ldap_service->tls_params == NULL) goto failed; if (lp_interfaces(task->lp_ctx) && lp_bind_interfaces_only(task->lp_ctx)) { struct interface *ifaces; int num_interfaces; int i; load_interfaces(task, lp_interfaces(task->lp_ctx), &ifaces); num_interfaces = iface_count(ifaces); /* We have been given an interfaces line, and been told to only bind to those interfaces. Create a socket per interface and bind to only these. */ for(i = 0; i < num_interfaces; i++) { const char *address = iface_n_ip(ifaces, i); status = add_socket(task->event_ctx, task->lp_ctx, model_ops, address, ldap_service); if (!NT_STATUS_IS_OK(status)) goto failed; } } else { status = add_socket(task->event_ctx, task->lp_ctx, model_ops, lp_socket_address(task->lp_ctx), ldap_service); if (!NT_STATUS_IS_OK(status)) goto failed; } ldapi_path = private_path(ldap_service, task->lp_ctx, "ldapi"); if (!ldapi_path) { goto failed; } status = stream_setup_socket(task->event_ctx, task->lp_ctx, model_ops, &ldap_stream_nonpriv_ops, "unix", ldapi_path, NULL, lp_socket_options(task->lp_ctx), ldap_service); talloc_free(ldapi_path); if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("ldapsrv failed to bind to %s - %s\n", ldapi_path, nt_errstr(status))); } #ifdef WITH_LDAPI_PRIV_SOCKET priv_dir = private_path(ldap_service, task->lp_ctx, "ldap_priv"); if (priv_dir == NULL) { goto failed; } /* * Make sure the directory for the privileged ldapi socket exists, and * is of the correct permissions */ if (!directory_create_or_exist(priv_dir, geteuid(), 0750)) { task_server_terminate(task, "Cannot create ldap " "privileged ldapi directory", true); return; } ldapi_path = talloc_asprintf(ldap_service, "%s/ldapi", priv_dir); talloc_free(priv_dir); if (ldapi_path == NULL) { goto failed; } status = stream_setup_socket(task->event_ctx, task->lp_ctx, model_ops, &ldap_stream_priv_ops, "unix", ldapi_path, NULL, lp_socket_options(task->lp_ctx), ldap_service); talloc_free(ldapi_path); if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("ldapsrv failed to bind to %s - %s\n", ldapi_path, nt_errstr(status))); } #endif return; failed: task_server_terminate(task, "Failed to startup ldap server task", true); }
static int init_sockets_smbd(const char *smb_ports, int listenset[FD_SETSIZE]) { int num_interfaces = iface_count(); char * ports; int num_sockets = 0; int i, s; /* use a reasonable default set of ports - listing on 445 and 139 */ if (!smb_ports) { ports = lp_smb_ports(); if (!ports || !*ports) { ports = smb_xstrdup(SMB_PORTS); } else { ports = smb_xstrdup(ports); } } else { ports = smb_xstrdup(smb_ports); } if (lp_interfaces() && lp_bind_interfaces_only()) { /* We have been given an interfaces line, and been told to only bind to those interfaces. Create a socket per interface and bind to only these. */ /* Now open a listen socket for each of the interfaces. */ for(i = 0; i < num_interfaces; i++) { struct in_addr *ifip = iface_n_ip(i); fstring tok; const char *ptr; if(ifip == NULL) { DEBUG(0,("init_sockets_smbd: interface %d has NULL IP address !\n", i)); continue; } for (ptr=ports; next_token(&ptr, tok, " \t,", sizeof(tok)); ) { unsigned port = atoi(tok); if (port == 0) { continue; } s = listenset[num_sockets] = open_socket_in(SOCK_STREAM, port, 0, ifip->s_addr, True); if (s < 0 || s >= FD_SETSIZE) return 0; /* ready to listen */ set_socket_options(s,"SO_KEEPALIVE"); set_socket_options(s,user_socket_options); /* Set server socket to non-blocking for the accept. */ set_blocking(s,False); if (listen(s, SMBD_LISTEN_BACKLOG) == -1) { DEBUG(0,("listen: %s\n",strerror(errno))); close(s); return 0; } num_sockets++; if (num_sockets >= FD_SETSIZE) { DEBUG(0,("init_sockets_smbd: Too many sockets to bind to\n")); return 0; } } } } else { /* Just bind to 0.0.0.0 - accept connections from anywhere. */ fstring tok; const char *ptr; num_interfaces = 1; for (ptr=ports; next_token(&ptr, tok, " \t,", sizeof(tok)); ) { unsigned port = atoi(tok); if (port == 0) continue; /* open an incoming socket */ s = open_socket_in(SOCK_STREAM, port, 0, interpret_addr(lp_socket_address()),True); if (s < 0 || s >= FD_SETSIZE) return 0; /* ready to listen */ set_socket_options(s,"SO_KEEPALIVE"); set_socket_options(s,user_socket_options); /* Set server socket to non-blocking for the accept. */ set_blocking(s,False); if (listen(s, SMBD_LISTEN_BACKLOG) == -1) { DEBUG(0,("init_sockets_smbd: listen: %s\n", strerror(errno))); close(s); return 0; } listenset[num_sockets] = s; num_sockets++; if (num_sockets >= FD_SETSIZE) { DEBUG(0,("init_sockets_smbd: Too many sockets to bind to\n")); return 0; } } } SAFE_FREE(ports); return num_sockets; }
static BOOL open_sockets_smbd(BOOL is_daemon, BOOL interactive, const char *smb_ports) { int num_interfaces = iface_count(); int num_sockets = 0; int fd_listenset[FD_SETSIZE]; fd_set listen_set; int s; int maxfd = 0; int i; char *ports; if (!is_daemon) { return open_sockets_inetd(); } #ifdef HAVE_ATEXIT { static int atexit_set; if(atexit_set == 0) { atexit_set=1; atexit(killkids); } } #endif #ifndef _XBOX /* Stop zombies */ CatchChild(); #endif FD_ZERO(&listen_set); /* use a reasonable default set of ports - listing on 445 and 139 */ if (!smb_ports) { ports = lp_smb_ports(); if (!ports || !*ports) { ports = smb_xstrdup(SMB_PORTS); } else { ports = smb_xstrdup(ports); } } else { ports = smb_xstrdup(smb_ports); } if (lp_interfaces() && lp_bind_interfaces_only()) { /* We have been given an interfaces line, and been told to only bind to those interfaces. Create a socket per interface and bind to only these. */ /* Now open a listen socket for each of the interfaces. */ for(i = 0; i < num_interfaces; i++) { struct in_addr *ifip = iface_n_ip(i); fstring tok; const char *ptr; if(ifip == NULL) { DEBUG(0,("open_sockets_smbd: interface %d has NULL IP address !\n", i)); continue; } for (ptr=ports; next_token(&ptr, tok, " \t,", sizeof(tok)); ) { unsigned port = atoi(tok); if (port == 0) { continue; } s = fd_listenset[num_sockets] = open_socket_in(SOCK_STREAM, port, 0, ifip->s_addr, True); if(s == -1) return False; /* ready to listen */ set_socket_options(s,"SO_KEEPALIVE"); set_socket_options(s,user_socket_options); /* Set server socket to non-blocking for the accept. */ set_blocking(s,False); if (listen(s, SMBD_LISTEN_BACKLOG) == -1) { DEBUG(0,("listen: %s\n",strerror(errno))); close(s); return False; } FD_SET(s,&listen_set); maxfd = MAX( maxfd, s); num_sockets++; if (num_sockets >= FD_SETSIZE) { DEBUG(0,("open_sockets_smbd: Too many sockets to bind to\n")); return False; } } } } else { /* Just bind to 0.0.0.0 - accept connections from anywhere. */ fstring tok; const char *ptr; num_interfaces = 1; for (ptr=ports; next_token(&ptr, tok, " \t,", sizeof(tok)); ) { unsigned port = atoi(tok); if (port == 0) continue; /* open an incoming socket */ s = open_socket_in(SOCK_STREAM, port, 0, interpret_addr(lp_socket_address()),True); if (s == -1) return(False); /* ready to listen */ #ifndef _XBOX set_socket_options(s,"SO_KEEPALIVE"); #endif set_socket_options(s,user_socket_options); /* Set server socket to non-blocking for the accept. */ set_blocking(s,False); if (listen(s, SMBD_LISTEN_BACKLOG) == -1) { DEBUG(0,("open_sockets_smbd: listen: %s\n", strerror(errno))); close(s); return False; } fd_listenset[num_sockets] = s; FD_SET(s,&listen_set); maxfd = MAX( maxfd, s); num_sockets++; if (num_sockets >= FD_SETSIZE) { DEBUG(0,("open_sockets_smbd: Too many sockets to bind to\n")); return False; } } } SAFE_FREE(ports); /* Listen to messages */ message_register(MSG_SMB_SAM_SYNC, msg_sam_sync); message_register(MSG_SMB_SAM_REPL, msg_sam_repl); message_register(MSG_SHUTDOWN, msg_exit_server); message_register(MSG_SMB_FILE_RENAME, msg_file_was_renamed); message_register(MSG_SMB_CONF_UPDATED, smb_conf_updated); #ifdef DEVELOPER message_register(MSG_SMB_INJECT_FAULT, msg_inject_fault); #endif /* now accept incoming connections - forking a new process for each incoming connection */ DEBUG(2,("waiting for a connection\n")); while (1) { fd_set lfds; int num; /* Free up temporary memory from the main smbd. */ lp_TALLOC_FREE(); /* Ensure we respond to PING and DEBUG messages from the main smbd. */ message_dispatch(); memcpy((char *)&lfds, (char *)&listen_set, sizeof(listen_set)); num = sys_select(maxfd+1,&lfds,NULL,NULL,NULL); if (num == -1 && errno == EINTR) { if (got_sig_term) { exit_server_cleanly(NULL); } /* check for sighup processing */ if (reload_after_sighup) { change_to_root_user(); DEBUG(1,("Reloading services after SIGHUP\n")); reload_services(False); reload_after_sighup = 0; } continue; } /* check if we need to reload services */ check_reload(time(NULL)); /* Find the sockets that are read-ready - accept on these. */ for( ; num > 0; num--) { struct sockaddr addr; socklen_t in_addrlen = sizeof(addr); s = -1; for(i = 0; i < num_sockets; i++) { if(FD_ISSET(fd_listenset[i],&lfds)) { s = fd_listenset[i]; /* Clear this so we don't look at it again. */ FD_CLR(fd_listenset[i],&lfds); break; } } smbd_set_server_fd(accept(s,&addr,&in_addrlen)); if (smbd_server_fd() == -1 && errno == EINTR) continue; if (smbd_server_fd() == -1) { DEBUG(0,("open_sockets_smbd: accept: %s\n", strerror(errno))); continue; } /* Ensure child is set to blocking mode */ set_blocking(smbd_server_fd(),True); if (smbd_server_fd() != -1 && interactive) { #ifdef _XBOX xb_IncClientCount(); #endif return True; } if (allowable_number_of_smbd_processes() && smbd_server_fd() != -1 && sys_fork()==0) { /* Child code ... */ /* close the listening socket(s) */ for(i = 0; i < num_sockets; i++) close(fd_listenset[i]); /* close our standard file descriptors */ close_low_fds(False); am_parent = 0; set_socket_options(smbd_server_fd(),"SO_KEEPALIVE"); set_socket_options(smbd_server_fd(),user_socket_options); /* this is needed so that we get decent entries in smbstatus for port 445 connects */ set_remote_machine_name(get_peer_addr(smbd_server_fd()), False); /* Reset the state of the random * number generation system, so * children do not get the same random * numbers as each other */ set_need_random_reseed(); /* tdb needs special fork handling - remove CLEAR_IF_FIRST flags */ if (tdb_reopen_all(1) == -1) { DEBUG(0,("tdb_reopen_all failed.\n")); smb_panic("tdb_reopen_all failed."); } return True; } /* The parent doesn't need this socket */ close(smbd_server_fd()); /* Sun May 6 18:56:14 2001 [email protected]: Clear the closed fd info out of server_fd -- and more importantly, out of client_fd in util_sock.c, to avoid a possible getpeername failure if we reopen the logs and use %I in the filename. */ smbd_set_server_fd(-1); /* Force parent to check log size after * spawning child. Fix from * [email protected]. The * parent smbd will log to logserver.smb. It * writes only two messages for each child * started/finished. But each child writes, * say, 50 messages also in logserver.smb, * begining with the debug_count of the * parent, before the child opens its own log * file logserver.client. In a worst case * scenario the size of logserver.smb would be * checked after about 50*50=2500 messages * (ca. 100kb). * */ force_check_log_size(); } /* end for num */ } /* end while 1 */ /* NOTREACHED return True; */ }