/* 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); }
/* open the smb server sockets */ static void samba3_smb_task_init(struct task_server *task) { NTSTATUS status; const struct model_ops *model_ops; model_ops = process_model_startup("standard"); if (model_ops == NULL) { goto failed; } task_server_set_title(task, "task[samba3_smb]"); if (lpcfg_interfaces(task->lp_ctx) && lpcfg_bind_interfaces_only(task->lp_ctx)) { int num_interfaces; int i; struct interface *ifaces; load_interface_list(task, task->lp_ctx, &ifaces); num_interfaces = iface_list_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_list_n_ip(ifaces, i); status = samba3_add_socket(task, task->event_ctx, task->lp_ctx, model_ops, address); if (!NT_STATUS_IS_OK(status)) goto failed; } } else { const char **wcard; int i; wcard = iface_list_wildcard(task, task->lp_ctx); if (wcard == NULL) { DEBUG(0,("No wildcard addresses available\n")); goto failed; } for (i=0; wcard[i]; i++) { status = samba3_add_socket(task, task->event_ctx, task->lp_ctx, model_ops, wcard[i]); if (!NT_STATUS_IS_OK(status)) goto failed; } talloc_free(wcard); } return; failed: task_server_terminate(task, "Failed to startup samba3 smb task", true); }
/* startup the winbind task */ static void winbind_task_init(struct task_server *task) { uint16_t port = 1; const struct model_ops *model_ops; NTSTATUS status; struct wbsrv_service *service; struct wbsrv_listen_socket *listen_socket; char *errstring; struct dom_sid *primary_sid; bool ok; task_server_set_title(task, "task[winbind]"); /* within the winbind task we want to be a single process, so ask for the single process model ops and pass these to the stream_setup_socket() call. */ model_ops = process_model_startup("single"); if (!model_ops) { task_server_terminate(task, "Can't find 'single' process model_ops", true); return; } /* Make sure the directory for the Samba3 socket exists, and is of the correct permissions */ ok = directory_create_or_exist_strict(lpcfg_winbindd_socket_directory(task->lp_ctx), geteuid(), 0755); if (!ok) { task_server_terminate(task, "Cannot create winbindd pipe directory", true); return; } /* Make sure the directory for the Samba3 socket exists, and is of the correct permissions */ ok = directory_create_or_exist_strict(lpcfg_winbindd_privileged_socket_directory(task->lp_ctx), geteuid(), 0750); if (!ok) { task_server_terminate(task, "Cannot create winbindd privileged pipe directory", true); return; } service = talloc_zero(task, struct wbsrv_service); if (!service) goto nomem; service->task = task; /* Find the primary SID, depending if we are a standalone * server (what good is winbind in this case, but anyway...), * or are in a domain as a member or a DC */ switch (lpcfg_server_role(service->task->lp_ctx)) { case ROLE_STANDALONE: primary_sid = secrets_get_domain_sid(service, service->task->lp_ctx, lpcfg_netbios_name(service->task->lp_ctx), &service->sec_channel_type, &errstring); if (!primary_sid) { char *message = talloc_asprintf(task, "Cannot start Winbind (standalone configuration): %s: " "Have you provisioned this server (%s) or changed it's name?", errstring, lpcfg_netbios_name(service->task->lp_ctx)); task_server_terminate(task, message, true); return; } break; case ROLE_DOMAIN_MEMBER: primary_sid = secrets_get_domain_sid(service, service->task->lp_ctx, lpcfg_workgroup(service->task->lp_ctx), &service->sec_channel_type, &errstring); if (!primary_sid) { char *message = talloc_asprintf(task, "Cannot start Winbind (domain member): %s: " "Have you joined the %s domain?", errstring, lpcfg_workgroup(service->task->lp_ctx)); task_server_terminate(task, message, true); return; } break; case ROLE_ACTIVE_DIRECTORY_DC: primary_sid = secrets_get_domain_sid(service, service->task->lp_ctx, lpcfg_workgroup(service->task->lp_ctx), &service->sec_channel_type, &errstring); if (!primary_sid) { char *message = talloc_asprintf(task, "Cannot start Winbind (domain controller): %s: " "Have you provisioned the %s domain?", errstring, lpcfg_workgroup(service->task->lp_ctx)); task_server_terminate(task, message, true); return; } break; case ROLE_DOMAIN_PDC: case ROLE_DOMAIN_BDC: task_server_terminate(task, "Cannot start 'samba' winbindd as a 'classic samba' DC: use winbindd instead", true); return; } service->primary_sid = primary_sid; service->idmap_ctx = idmap_init(service, task->event_ctx, task->lp_ctx); if (service->idmap_ctx == NULL) { task_server_terminate(task, "Failed to load idmap database", true); return; } service->priv_pipe_dir = lpcfg_winbindd_privileged_socket_directory(task->lp_ctx); service->pipe_dir = lpcfg_winbindd_socket_directory(task->lp_ctx); /* setup the unprivileged samba3 socket */ listen_socket = talloc(service, struct wbsrv_listen_socket); if (!listen_socket) goto nomem; listen_socket->socket_path = talloc_asprintf(listen_socket, "%s/%s", service->pipe_dir, WINBINDD_SOCKET_NAME); if (!listen_socket->socket_path) goto nomem; listen_socket->service = service; listen_socket->privileged = false; status = stream_setup_socket(task, task->event_ctx, task->lp_ctx, model_ops, &wbsrv_ops, "unix", listen_socket->socket_path, &port, lpcfg_socket_options(task->lp_ctx), listen_socket); if (!NT_STATUS_IS_OK(status)) goto listen_failed; /* setup the privileged samba3 socket */ listen_socket = talloc(service, struct wbsrv_listen_socket); if (!listen_socket) goto nomem; listen_socket->socket_path = talloc_asprintf(listen_socket, "%s/%s", service->priv_pipe_dir, WINBINDD_SOCKET_NAME); if (!listen_socket->socket_path) goto nomem; listen_socket->service = service; listen_socket->privileged = true; status = stream_setup_socket(task, task->event_ctx, task->lp_ctx, model_ops, &wbsrv_ops, "unix", listen_socket->socket_path, &port, lpcfg_socket_options(task->lp_ctx), listen_socket); if (!NT_STATUS_IS_OK(status)) goto listen_failed; status = wbsrv_init_irpc(service); if (!NT_STATUS_IS_OK(status)) goto irpc_failed; return; listen_failed: DEBUG(0,("stream_setup_socket(path=%s) failed - %s\n", listen_socket->socket_path, nt_errstr(status))); task_server_terminate(task, nt_errstr(status), true); return; irpc_failed: DEBUG(0,("wbsrv_init_irpc() failed - %s\n", nt_errstr(status))); task_server_terminate(task, nt_errstr(status), true); return; nomem: task_server_terminate(task, nt_errstr(NT_STATUS_NO_MEMORY), true); return; }
/* 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); }
/* startup the wrepl port 42 server sockets */ NTSTATUS wreplsrv_setup_sockets(struct wreplsrv_service *service, struct loadparm_context *lp_ctx) { NTSTATUS status; struct task_server *task = service->task; const struct model_ops *model_ops; const char *address; uint16_t port = WINS_REPLICATION_PORT; /* within the wrepl task we want to be a single process, so ask for the single process model ops and pass these to the stream_setup_socket() call. */ model_ops = process_model_startup("single"); if (!model_ops) { DEBUG(0,("Can't find 'single' process model_ops")); return NT_STATUS_INTERNAL_ERROR; } if (lpcfg_interfaces(lp_ctx) && lpcfg_bind_interfaces_only(lp_ctx)) { int num_interfaces; int i; struct interface *ifaces; load_interface_list(task, lp_ctx, &ifaces); num_interfaces = iface_list_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++) { if (!iface_list_n_is_v4(ifaces, i)) { continue; } address = iface_list_n_ip(ifaces, i); status = stream_setup_socket(task, task->event_ctx, task->lp_ctx, model_ops, &wreplsrv_stream_ops, "ipv4", address, &port, lpcfg_socket_options(task->lp_ctx), service); if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("stream_setup_socket(address=%s,port=%u) failed - %s\n", address, port, nt_errstr(status))); return status; } } } else { address = "0.0.0.0"; status = stream_setup_socket(task, task->event_ctx, task->lp_ctx, model_ops, &wreplsrv_stream_ops, "ipv4", address, &port, lpcfg_socket_options(task->lp_ctx), service); if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("stream_setup_socket(address=%s,port=%u) failed - %s\n", address, port, nt_errstr(status))); return status; } } return NT_STATUS_OK; }
/* called when we get a new connection */ NTSTATUS wreplsrv_in_connection_merge(struct wreplsrv_partner *partner, uint32_t peer_assoc_ctx, struct tstream_context **stream, struct wreplsrv_in_connection **_wrepl_in) { struct wreplsrv_service *service = partner->service; struct wreplsrv_in_connection *wrepl_in; const struct model_ops *model_ops; struct stream_connection *conn; struct tevent_req *subreq; NTSTATUS status; /* within the wrepl task we want to be a single process, so ask for the single process model ops and pass these to the stream_setup_socket() call. */ model_ops = process_model_startup("single"); if (!model_ops) { DEBUG(0,("Can't find 'single' process model_ops")); return NT_STATUS_INTERNAL_ERROR; } wrepl_in = talloc_zero(partner, struct wreplsrv_in_connection); NT_STATUS_HAVE_NO_MEMORY(wrepl_in); wrepl_in->service = service; wrepl_in->partner = partner; wrepl_in->tstream = talloc_move(wrepl_in, stream); wrepl_in->assoc_ctx.peer_ctx = peer_assoc_ctx; status = stream_new_connection_merge(service->task->event_ctx, service->task->lp_ctx, model_ops, &wreplsrv_stream_ops, service->task->msg_ctx, wrepl_in, &conn); NT_STATUS_NOT_OK_RETURN(status); /* * make the wreplsrv_in_connection structure a child of the * stream_connection, to match the hierarchy of wreplsrv_accept */ wrepl_in->conn = conn; talloc_steal(conn, wrepl_in); wrepl_in->send_queue = tevent_queue_create(wrepl_in, "wreplsrv_in_connection_merge"); if (wrepl_in->send_queue == NULL) { stream_terminate_connection(conn, "wreplsrv_in_connection_merge: out of memory"); return NT_STATUS_NO_MEMORY; } /* * The wrepl pdu's has the length as 4 byte (initial_read_size), * packet_full_request_u32 provides the pdu length then. */ subreq = tstream_read_pdu_blob_send(wrepl_in, wrepl_in->conn->event.ctx, wrepl_in->tstream, 4, /* initial_read_size */ packet_full_request_u32, wrepl_in); if (subreq == NULL) { wreplsrv_terminate_in_connection(wrepl_in, "wreplsrv_in_connection_merge: " "no memory for tstream_read_pdu_blob_send"); return NT_STATUS_NO_MEMORY; } tevent_req_set_callback(subreq, wreplsrv_call_loop, wrepl_in); *_wrepl_in = wrepl_in; return NT_STATUS_OK; }
/* startup the winbind task */ static void winbind_task_init(struct task_server *task) { uint16_t port = 1; const struct model_ops *model_ops; NTSTATUS status; struct wbsrv_service *service; struct wbsrv_listen_socket *listen_socket; task_server_set_title(task, "task[winbind]"); /* within the winbind task we want to be a single process, so ask for the single process model ops and pass these to the stream_setup_socket() call. */ model_ops = process_model_startup(task->event_ctx, "single"); if (!model_ops) { task_server_terminate(task, "Can't find 'single' process model_ops", true); return; } /* Make sure the directory for the Samba3 socket exists, and is of the correct permissions */ if (!directory_create_or_exist(lp_winbindd_socket_directory(task->lp_ctx), geteuid(), 0755)) { task_server_terminate(task, "Cannot create winbindd pipe directory", true); return; } /* Make sure the directory for the Samba3 socket exists, and is of the correct permissions */ if (!directory_create_or_exist(lp_winbindd_privileged_socket_directory(task->lp_ctx), geteuid(), 0750)) { task_server_terminate(task, "Cannot create winbindd privileged pipe directory", true); return; } service = talloc_zero(task, struct wbsrv_service); if (!service) goto nomem; service->task = task; status = wbsrv_setup_domains(service); if (!NT_STATUS_IS_OK(status)) { task_server_terminate(task, nt_errstr(status), true); return; } service->idmap_ctx = idmap_init(service, task->event_ctx, task->lp_ctx); if (service->idmap_ctx == NULL) { task_server_terminate(task, "Failed to load idmap database", true); return; } /* setup the unprivileged samba3 socket */ listen_socket = talloc(service, struct wbsrv_listen_socket); if (!listen_socket) goto nomem; listen_socket->socket_path = talloc_asprintf(listen_socket, "%s/%s", lp_winbindd_socket_directory(task->lp_ctx), WINBINDD_SAMBA3_SOCKET); if (!listen_socket->socket_path) goto nomem; listen_socket->service = service; listen_socket->privileged = false; status = stream_setup_socket(task->event_ctx, task->lp_ctx, model_ops, &wbsrv_ops, "unix", listen_socket->socket_path, &port, lp_socket_options(task->lp_ctx), listen_socket); if (!NT_STATUS_IS_OK(status)) goto listen_failed; /* setup the privileged samba3 socket */ listen_socket = talloc(service, struct wbsrv_listen_socket); if (!listen_socket) goto nomem; listen_socket->socket_path = service->priv_socket_path = talloc_asprintf(listen_socket, "%s/%s", lp_winbindd_privileged_socket_directory(task->lp_ctx), WINBINDD_SAMBA3_SOCKET); if (!listen_socket->socket_path) goto nomem; if (!listen_socket->socket_path) goto nomem; listen_socket->service = service; listen_socket->privileged = true; status = stream_setup_socket(task->event_ctx, task->lp_ctx, model_ops, &wbsrv_ops, "unix", listen_socket->socket_path, &port, lp_socket_options(task->lp_ctx), listen_socket); if (!NT_STATUS_IS_OK(status)) goto listen_failed; status = wbsrv_init_irpc(service); if (!NT_STATUS_IS_OK(status)) goto irpc_failed; return; listen_failed: DEBUG(0,("stream_setup_socket(path=%s) failed - %s\n", listen_socket->socket_path, nt_errstr(status))); task_server_terminate(task, nt_errstr(status), true); return; irpc_failed: DEBUG(0,("wbsrv_init_irpc() failed - %s\n", nt_errstr(status))); task_server_terminate(task, nt_errstr(status), true); return; nomem: task_server_terminate(task, nt_errstr(NT_STATUS_NO_MEMORY), true); return; }