/* startup the nbtd task */ static void nbtd_task_init(struct task_server *task) { struct nbtd_server *nbtsrv; NTSTATUS status; struct interface *ifaces; load_interface_list(task, task->lp_ctx, &ifaces); if (iface_list_count(ifaces) == 0) { task_server_terminate(task, "nbtd: no network interfaces configured", false); return; } if (lpcfg_disable_netbios(task->lp_ctx)) { task_server_terminate(task, "nbtd: 'disable netbios = yes' set in smb.conf, shutting down nbt server", false); return; } task_server_set_title(task, "task[nbtd]"); nbtsrv = talloc(task, struct nbtd_server); if (nbtsrv == NULL) { task_server_terminate(task, "nbtd: out of memory", true); return; } nbtsrv->task = task; nbtsrv->interfaces = NULL; nbtsrv->bcast_interface = NULL; nbtsrv->wins_interface = NULL; /* start listening on the configured network interfaces */ status = nbtd_startup_interfaces(nbtsrv, task->lp_ctx, ifaces); if (!NT_STATUS_IS_OK(status)) { task_server_terminate(task, "nbtd failed to setup interfaces", true); return; } nbtsrv->sam_ctx = samdb_connect(nbtsrv, task->event_ctx, task->lp_ctx, system_session(task->lp_ctx), 0); if (nbtsrv->sam_ctx == NULL) { task_server_terminate(task, "nbtd failed to open samdb", true); return; } /* start the WINS server, if appropriate */ status = nbtd_winsserver_init(nbtsrv); if (!NT_STATUS_IS_OK(status)) { task_server_terminate(task, "nbtd failed to start WINS server", true); return; } nbtd_register_irpc(nbtsrv); /* start the process of registering our names on all interfaces */ nbtd_register_names(nbtsrv); irpc_add_name(task->msg_ctx, "nbt_server"); }
/* startup the cldapd task */ static void cldapd_task_init(struct task_server *task) { struct cldapd_server *cldapd; NTSTATUS status; struct interface *ifaces; load_interface_list(task, task->lp_ctx, &ifaces); if (iface_list_count(ifaces) == 0) { task_server_terminate(task, "cldapd: no network interfaces configured", false); return; } switch (lpcfg_server_role(task->lp_ctx)) { case ROLE_STANDALONE: task_server_terminate(task, "cldap_server: no CLDAP server required in standalone configuration", false); return; case ROLE_DOMAIN_MEMBER: task_server_terminate(task, "cldap_server: no CLDAP server required in member server configuration", false); return; case ROLE_ACTIVE_DIRECTORY_DC: /* Yes, we want an CLDAP server */ break; } task_server_set_title(task, "task[cldapd]"); cldapd = talloc(task, struct cldapd_server); if (cldapd == NULL) { task_server_terminate(task, "cldapd: out of memory", true); return; } cldapd->task = task; cldapd->samctx = samdb_connect(cldapd, task->event_ctx, task->lp_ctx, system_session(task->lp_ctx), NULL, 0); if (cldapd->samctx == NULL) { task_server_terminate(task, "cldapd failed to open samdb", true); return; } /* start listening on the configured network interfaces */ status = cldapd_startup_interfaces(cldapd, task->lp_ctx, ifaces); if (!NT_STATUS_IS_OK(status)) { task_server_terminate(task, "cldapd failed to setup interfaces", true); return; } irpc_add_name(task->msg_ctx, "cldap_server"); }
/* setup messaging for the top level samba (parent) task */ static NTSTATUS setup_parent_messaging(struct tevent_context *event_ctx, struct loadparm_context *lp_ctx) { struct imessaging_context *msg; NTSTATUS status; msg = imessaging_init(talloc_autofree_context(), lpcfg_imessaging_path(event_ctx, lp_ctx), cluster_id(0, SAMBA_PARENT_TASKID), event_ctx, false); NT_STATUS_HAVE_NO_MEMORY(msg); irpc_add_name(msg, "samba"); status = IRPC_REGISTER(msg, irpc, SAMBA_TERMINATE, samba_terminate, NULL); return status; }
/* open the smb server sockets */ static void smbsrv_task_init(struct task_server *task) { NTSTATUS status; task_server_set_title(task, "task[smbsrv]"); 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 = smbsrv_add_socket(task, task->event_ctx, task->lp_ctx, task->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 = smbsrv_add_socket(task, task->event_ctx, task->lp_ctx, task->model_ops, wcard[i]); if (!NT_STATUS_IS_OK(status)) goto failed; } talloc_free(wcard); } irpc_add_name(task->msg_ctx, "smb_server"); return; failed: task_server_terminate(task, "Failed to startup smb server task", true); }
/* startup the WINS server, if configured */ NTSTATUS nbtd_winsserver_init(struct nbtd_server *nbtsrv) { uint32_t tmp; const char *owner; if (!lpcfg_we_are_a_wins_server(nbtsrv->task->lp_ctx)) { nbtsrv->winssrv = NULL; return NT_STATUS_OK; } nbtsrv->winssrv = talloc_zero(nbtsrv, struct wins_server); NT_STATUS_HAVE_NO_MEMORY(nbtsrv->winssrv); nbtsrv->winssrv->config.max_renew_interval = lpcfg_max_wins_ttl(nbtsrv->task->lp_ctx); nbtsrv->winssrv->config.min_renew_interval = lpcfg_min_wins_ttl(nbtsrv->task->lp_ctx); tmp = lpcfg_parm_int(nbtsrv->task->lp_ctx, NULL, "wreplsrv", "tombstone_interval", 6*24*60*60); nbtsrv->winssrv->config.tombstone_interval = tmp; tmp = lpcfg_parm_int(nbtsrv->task->lp_ctx, NULL, "wreplsrv"," tombstone_timeout", 1*24*60*60); nbtsrv->winssrv->config.tombstone_timeout = tmp; owner = lpcfg_parm_string(nbtsrv->task->lp_ctx, NULL, "winsdb", "local_owner"); if (owner == NULL) { struct interface *ifaces; load_interface_list(nbtsrv->task, nbtsrv->task->lp_ctx, &ifaces); owner = iface_list_first_v4(ifaces); } nbtsrv->winssrv->wins_db = winsdb_connect(nbtsrv->winssrv, nbtsrv->task->event_ctx, nbtsrv->task->lp_ctx, owner, WINSDB_HANDLE_CALLER_NBTD); if (!nbtsrv->winssrv->wins_db) { return NT_STATUS_INTERNAL_DB_ERROR; } irpc_add_name(nbtsrv->task->msg_ctx, "wins_server"); return NT_STATUS_OK; }
/* startup the kdc task */ static void kdc_task_init(struct task_server *task) { struct kdc_server *kdc; krb5_kdc_configuration *kdc_config = NULL; NTSTATUS status; krb5_error_code ret; struct interface *ifaces; int ldb_ret; switch (lpcfg_server_role(task->lp_ctx)) { case ROLE_STANDALONE: task_server_terminate(task, "kdc: no KDC required in standalone configuration", false); return; case ROLE_DOMAIN_MEMBER: task_server_terminate(task, "kdc: no KDC required in member server configuration", false); return; case ROLE_DOMAIN_PDC: case ROLE_DOMAIN_BDC: task_server_terminate(task, "Cannot start KDC as a 'classic Samba' DC", true); return; case ROLE_ACTIVE_DIRECTORY_DC: /* Yes, we want a KDC */ break; } load_interface_list(task, task->lp_ctx, &ifaces); if (iface_list_count(ifaces) == 0) { task_server_terminate(task, "kdc: no network interfaces configured", false); return; } task_server_set_title(task, "task[kdc]"); kdc = talloc_zero(task, struct kdc_server); if (kdc == NULL) { task_server_terminate(task, "kdc: out of memory", true); return; } kdc->task = task; /* get a samdb connection */ kdc->samdb = samdb_connect(kdc, kdc->task->event_ctx, kdc->task->lp_ctx, system_session(kdc->task->lp_ctx), NULL, 0); if (!kdc->samdb) { DEBUG(1,("kdc_task_init: unable to connect to samdb\n")); task_server_terminate(task, "kdc: krb5_init_context samdb connect failed", true); return; } ldb_ret = samdb_rodc(kdc->samdb, &kdc->am_rodc); if (ldb_ret != LDB_SUCCESS) { DEBUG(1, ("kdc_task_init: Cannot determine if we are an RODC: %s\n", ldb_errstring(kdc->samdb))); task_server_terminate(task, "kdc: krb5_init_context samdb RODC connect failed", true); return; } kdc->proxy_timeout = lpcfg_parm_int(kdc->task->lp_ctx, NULL, "kdc", "proxy timeout", 5); initialize_krb5_error_table(); ret = smb_krb5_init_context(kdc, task->lp_ctx, &kdc->smb_krb5_context); if (ret) { DEBUG(1,("kdc_task_init: krb5_init_context failed (%s)\n", error_message(ret))); task_server_terminate(task, "kdc: krb5_init_context failed", true); return; } krb5_add_et_list(kdc->smb_krb5_context->krb5_context, initialize_hdb_error_table_r); ret = krb5_kdc_get_config(kdc->smb_krb5_context->krb5_context, &kdc_config); if(ret) { task_server_terminate(task, "kdc: failed to get KDC configuration", true); return; } kdc_config->logf = (krb5_log_facility *)kdc->smb_krb5_context->pvt_log_data; kdc_config->db = talloc(kdc, struct HDB *); if (!kdc_config->db) { task_server_terminate(task, "kdc: out of memory", true); return; } kdc_config->num_db = 1; /* * This restores the behavior before * commit 255e3e18e00f717d99f3bc57c8a8895ff624f3c3 * s4:heimdal: import lorikeet-heimdal-201107150856 * (commit 48936803fae4a2fb362c79365d31f420c917b85b) * * as_use_strongest_session_key,preauth_use_strongest_session_key * and tgs_use_strongest_session_key are input to the * _kdc_find_etype() function. The old bahavior is in * the use_strongest_session_key=FALSE code path. * (The only remaining difference in _kdc_find_etype() * is the is_preauth parameter.) * * The old behavior in the _kdc_get_preferred_key() * function is use_strongest_server_key=TRUE. */ kdc_config->as_use_strongest_session_key = false; kdc_config->preauth_use_strongest_session_key = false; kdc_config->tgs_use_strongest_session_key = false; kdc_config->use_strongest_server_key = true; kdc_config->autodetect_referrals = false; /* Register hdb-samba4 hooks for use as a keytab */ kdc->base_ctx = talloc_zero(kdc, struct samba_kdc_base_context); if (!kdc->base_ctx) { task_server_terminate(task, "kdc: out of memory", true); return; } kdc->base_ctx->ev_ctx = task->event_ctx; kdc->base_ctx->lp_ctx = task->lp_ctx; kdc->base_ctx->msg_ctx = task->msg_ctx; status = hdb_samba4_create_kdc(kdc->base_ctx, kdc->smb_krb5_context->krb5_context, &kdc_config->db[0]); if (!NT_STATUS_IS_OK(status)) { task_server_terminate(task, "kdc: hdb_samba4_create_kdc (setup KDC database) failed", true); return; } ret = krb5_plugin_register(kdc->smb_krb5_context->krb5_context, PLUGIN_TYPE_DATA, "hdb", &hdb_samba4_interface); if(ret) { task_server_terminate(task, "kdc: failed to register hdb plugin", true); return; } ret = krb5_kt_register(kdc->smb_krb5_context->krb5_context, &hdb_kt_ops); if(ret) { task_server_terminate(task, "kdc: failed to register keytab plugin", true); return; } kdc->keytab_name = talloc_asprintf(kdc, "HDB:samba4&%p", kdc->base_ctx); if (kdc->keytab_name == NULL) { task_server_terminate(task, "kdc: Failed to set keytab name", true); return; } /* Register WinDC hooks */ ret = krb5_plugin_register(kdc->smb_krb5_context->krb5_context, PLUGIN_TYPE_DATA, "windc", &windc_plugin_table); if(ret) { task_server_terminate(task, "kdc: failed to register windc plugin", true); return; } ret = krb5_kdc_windc_init(kdc->smb_krb5_context->krb5_context); if(ret) { task_server_terminate(task, "kdc: failed to init windc plugin", true); return; } ret = krb5_kdc_pkinit_config(kdc->smb_krb5_context->krb5_context, kdc_config); if(ret) { task_server_terminate(task, "kdc: failed to init kdc pkinit subsystem", true); return; } kdc->private_data = kdc_config; /* start listening on the configured network interfaces */ status = kdc_startup_interfaces(kdc, task->lp_ctx, ifaces, task->model_ops); if (!NT_STATUS_IS_OK(status)) { task_server_terminate(task, "kdc failed to setup interfaces", true); return; } status = IRPC_REGISTER(task->msg_ctx, irpc, KDC_CHECK_GENERIC_KERBEROS, kdc_check_generic_kerberos, kdc); if (!NT_STATUS_IS_OK(status)) { task_server_terminate(task, "kdc failed to setup monitoring", true); return; } irpc_add_name(task->msg_ctx, "kdc_server"); }
/* startup the dsdb replicator service task */ static void dreplsrv_task_init(struct task_server *task) { WERROR status; struct dreplsrv_service *service; uint32_t periodic_startup_interval; switch (lp_server_role(task->lp_ctx)) { case ROLE_STANDALONE: task_server_terminate(task, "dreplsrv: no DSDB replication required in standalone configuration"); return; case ROLE_DOMAIN_MEMBER: task_server_terminate(task, "dreplsrv: no DSDB replication required in domain member configuration"); return; case ROLE_DOMAIN_CONTROLLER: /* Yes, we want DSDB replication */ break; } task_server_set_title(task, "task[dreplsrv]"); service = talloc_zero(task, struct dreplsrv_service); if (!service) { task_server_terminate(task, "dreplsrv_task_init: out of memory"); return; } service->task = task; service->startup_time = timeval_current(); task->private_data = service; status = dreplsrv_init_creds(service); if (!W_ERROR_IS_OK(status)) { task_server_terminate(task, talloc_asprintf(task, "dreplsrv: Failed to obtain server credentials: %s\n", win_errstr(status))); return; } status = dreplsrv_connect_samdb(service, task->lp_ctx); if (!W_ERROR_IS_OK(status)) { task_server_terminate(task, talloc_asprintf(task, "dreplsrv: Failed to connect to local samdb: %s\n", win_errstr(status))); return; } status = dreplsrv_load_partitions(service); if (!W_ERROR_IS_OK(status)) { task_server_terminate(task, talloc_asprintf(task, "dreplsrv: Failed to load partitions: %s\n", win_errstr(status))); return; } periodic_startup_interval = lp_parm_int(task->lp_ctx, NULL, "dreplsrv", "periodic_startup_interval", 15); /* in seconds */ service->periodic.interval = lp_parm_int(task->lp_ctx, NULL, "dreplsrv", "periodic_interval", 300); /* in seconds */ status = dreplsrv_periodic_schedule(service, periodic_startup_interval); if (!W_ERROR_IS_OK(status)) { task_server_terminate(task, talloc_asprintf(task, "dreplsrv: Failed to periodic schedule: %s\n", win_errstr(status))); return; } irpc_add_name(task->msg_ctx, "dreplsrv"); }
/* initialise a server_context from a open socket and register a event handler for reading from that socket */ static void ldapsrv_accept(struct stream_connection *c, struct auth_session_info *session_info) { struct ldapsrv_service *ldapsrv_service = talloc_get_type(c->private_data, struct ldapsrv_service); struct ldapsrv_connection *conn; struct cli_credentials *server_credentials; struct socket_address *socket_address; NTSTATUS status; int port; conn = talloc_zero(c, struct ldapsrv_connection); if (!conn) { stream_terminate_connection(c, "ldapsrv_accept: out of memory"); return; } conn->packet = NULL; conn->connection = c; conn->service = ldapsrv_service; conn->sockets.raw = c->socket; conn->lp_ctx = ldapsrv_service->task->lp_ctx; c->private_data = conn; socket_address = socket_get_my_addr(c->socket, conn); if (!socket_address) { ldapsrv_terminate_connection(conn, "ldapsrv_accept: failed to obtain local socket address!"); return; } port = socket_address->port; talloc_free(socket_address); if (port == 636) { struct socket_context *tls_socket = tls_init_server(ldapsrv_service->tls_params, c->socket, c->event.fde, NULL); if (!tls_socket) { ldapsrv_terminate_connection(conn, "ldapsrv_accept: tls_init_server() failed"); return; } talloc_steal(c, tls_socket); c->socket = tls_socket; conn->sockets.tls = tls_socket; } else if (port == 3268) /* Global catalog */ { conn->global_catalog = true; } conn->packet = packet_init(conn); if (conn->packet == NULL) { ldapsrv_terminate_connection(conn, "out of memory"); return; } packet_set_private(conn->packet, conn); packet_set_socket(conn->packet, c->socket); packet_set_callback(conn->packet, ldapsrv_decode); packet_set_full_request(conn->packet, ldap_full_packet); packet_set_error_handler(conn->packet, ldapsrv_error_handler); packet_set_event_context(conn->packet, c->event.ctx); packet_set_fde(conn->packet, c->event.fde); packet_set_serialise(conn->packet); if (conn->sockets.tls) { packet_set_unreliable_select(conn->packet); } /* Ensure we don't get packets until the database is ready below */ packet_recv_disable(conn->packet); server_credentials = cli_credentials_init(conn); if (!server_credentials) { stream_terminate_connection(c, "Failed to init server credentials\n"); return; } cli_credentials_set_conf(server_credentials, conn->lp_ctx); status = cli_credentials_set_machine_account(server_credentials, conn->lp_ctx); if (!NT_STATUS_IS_OK(status)) { stream_terminate_connection(c, talloc_asprintf(conn, "Failed to obtain server credentials, perhaps a standalone server?: %s\n", nt_errstr(status))); return; } conn->server_credentials = server_credentials; conn->session_info = talloc_move(conn, &session_info); if (!NT_STATUS_IS_OK(ldapsrv_backend_Init(conn))) { ldapsrv_terminate_connection(conn, "backend Init failed"); return; } /* load limits from the conf partition */ ldapsrv_load_limits(conn); /* should we fail on error ? */ /* register the server */ irpc_add_name(c->msg_ctx, "ldap_server"); /* set connections limits */ conn->limits.ite = event_add_timed(c->event.ctx, conn, timeval_current_ofs(conn->limits.initial_timeout, 0), ldapsrv_conn_init_timeout, conn); packet_recv_enable(conn->packet); }
/* called when we get a new connection */ static void wreplsrv_accept(struct stream_connection *conn) { struct wreplsrv_service *service = talloc_get_type(conn->private_data, struct wreplsrv_service); struct wreplsrv_in_connection *wrepl_conn; struct tsocket_address *peer_addr; char *peer_ip; struct tevent_req *subreq; int rc; wrepl_conn = talloc_zero(conn, struct wreplsrv_in_connection); if (wrepl_conn == NULL) { stream_terminate_connection(conn, "wreplsrv_accept: out of memory"); return; } wrepl_conn->send_queue = tevent_queue_create(conn, "wrepl_accept"); if (wrepl_conn->send_queue == NULL) { stream_terminate_connection(conn, "wrepl_accept: out of memory"); return; } TALLOC_FREE(conn->event.fde); rc = tstream_bsd_existing_socket(wrepl_conn, socket_get_fd(conn->socket), &wrepl_conn->tstream); if (rc < 0) { stream_terminate_connection(conn, "wrepl_accept: out of memory"); return; } socket_set_flags(conn->socket, SOCKET_FLAG_NOCLOSE); wrepl_conn->conn = conn; wrepl_conn->service = service; peer_addr = conn->remote_address; if (!tsocket_address_is_inet(peer_addr, "ipv4")) { DEBUG(0,("wreplsrv_accept: non ipv4 peer addr '%s'\n", tsocket_address_string(peer_addr, wrepl_conn))); wreplsrv_terminate_in_connection(wrepl_conn, "wreplsrv_accept: " "invalid peer IP"); return; } peer_ip = tsocket_address_inet_addr_string(peer_addr, wrepl_conn); if (peer_ip == NULL) { wreplsrv_terminate_in_connection(wrepl_conn, "wreplsrv_accept: " "could not convert peer IP into a string"); return; } wrepl_conn->partner = wreplsrv_find_partner(service, peer_ip); irpc_add_name(conn->msg_ctx, "wreplsrv_connection"); /* * 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_conn, wrepl_conn->conn->event.ctx, wrepl_conn->tstream, 4, /* initial_read_size */ packet_full_request_u32, wrepl_conn); if (subreq == NULL) { wreplsrv_terminate_in_connection(wrepl_conn, "wrepl_accept: " "no memory for tstream_read_pdu_blob_send"); return; } tevent_req_set_callback(subreq, wreplsrv_call_loop, wrepl_conn); }
/* initialise a server_context from a open socket and register a event handler for reading from that socket */ static void ldapsrv_accept(struct stream_connection *c, struct auth_session_info *session_info, bool is_privileged) { struct ldapsrv_service *ldapsrv_service = talloc_get_type(c->private_data, struct ldapsrv_service); struct ldapsrv_connection *conn; struct cli_credentials *server_credentials; struct socket_address *socket_address; NTSTATUS status; int port; int ret; struct tevent_req *subreq; struct timeval endtime; conn = talloc_zero(c, struct ldapsrv_connection); if (!conn) { stream_terminate_connection(c, "ldapsrv_accept: out of memory"); return; } conn->is_privileged = is_privileged; conn->sockets.send_queue = tevent_queue_create(conn, "ldapsev send queue"); if (conn->sockets.send_queue == NULL) { stream_terminate_connection(c, "ldapsrv_accept: tevent_queue_create failed"); return; } TALLOC_FREE(c->event.fde); ret = tstream_bsd_existing_socket(conn, socket_get_fd(c->socket), &conn->sockets.raw); if (ret == -1) { stream_terminate_connection(c, "ldapsrv_accept: out of memory"); return; } socket_set_flags(c->socket, SOCKET_FLAG_NOCLOSE); conn->connection = c; conn->service = ldapsrv_service; conn->lp_ctx = ldapsrv_service->task->lp_ctx; c->private_data = conn; socket_address = socket_get_my_addr(c->socket, conn); if (!socket_address) { ldapsrv_terminate_connection(conn, "ldapsrv_accept: failed to obtain local socket address!"); return; } port = socket_address->port; talloc_free(socket_address); if (port == 3268 || port == 3269) /* Global catalog */ { conn->global_catalog = true; } server_credentials = cli_credentials_init(conn); if (!server_credentials) { stream_terminate_connection(c, "Failed to init server credentials\n"); return; } cli_credentials_set_conf(server_credentials, conn->lp_ctx); status = cli_credentials_set_machine_account(server_credentials, conn->lp_ctx); if (!NT_STATUS_IS_OK(status)) { stream_terminate_connection(c, talloc_asprintf(conn, "Failed to obtain server credentials, perhaps a standalone server?: %s\n", nt_errstr(status))); return; } conn->server_credentials = server_credentials; conn->session_info = session_info; if (!NT_STATUS_IS_OK(ldapsrv_backend_Init(conn))) { ldapsrv_terminate_connection(conn, "backend Init failed"); return; } /* load limits from the conf partition */ ldapsrv_load_limits(conn); /* should we fail on error ? */ /* register the server */ irpc_add_name(c->msg_ctx, "ldap_server"); conn->sockets.active = conn->sockets.raw; if (port != 636 && port != 3269) { ldapsrv_call_read_next(conn); return; } endtime = timeval_current_ofs(conn->limits.conn_idle_time, 0); subreq = tstream_tls_accept_send(conn, conn->connection->event.ctx, conn->sockets.raw, conn->service->tls_params); if (subreq == NULL) { ldapsrv_terminate_connection(conn, "ldapsrv_accept: " "no memory for tstream_tls_accept_send"); return; } tevent_req_set_endtime(subreq, conn->connection->event.ctx, endtime); tevent_req_set_callback(subreq, ldapsrv_accept_tls_done, conn); }
/* startup the dsdb replicator service task */ static void dreplsrv_task_init(struct task_server *task) { WERROR status; struct dreplsrv_service *service; uint32_t periodic_startup_interval; switch (lpcfg_server_role(task->lp_ctx)) { case ROLE_STANDALONE: task_server_terminate(task, "dreplsrv: no DSDB replication required in standalone configuration", false); return; case ROLE_DOMAIN_MEMBER: task_server_terminate(task, "dreplsrv: no DSDB replication required in domain member configuration", false); return; case ROLE_ACTIVE_DIRECTORY_DC: /* Yes, we want DSDB replication */ break; } task_server_set_title(task, "task[dreplsrv]"); service = talloc_zero(task, struct dreplsrv_service); if (!service) { task_server_terminate(task, "dreplsrv_task_init: out of memory", true); return; } service->task = task; service->startup_time = timeval_current(); task->private_data = service; status = dreplsrv_init_creds(service); if (!W_ERROR_IS_OK(status)) { task_server_terminate(task, talloc_asprintf(task, "dreplsrv: Failed to obtain server credentials: %s\n", win_errstr(status)), true); return; } status = dreplsrv_connect_samdb(service, task->lp_ctx); if (!W_ERROR_IS_OK(status)) { task_server_terminate(task, talloc_asprintf(task, "dreplsrv: Failed to connect to local samdb: %s\n", win_errstr(status)), true); return; } status = dreplsrv_load_partitions(service); if (!W_ERROR_IS_OK(status)) { task_server_terminate(task, talloc_asprintf(task, "dreplsrv: Failed to load partitions: %s\n", win_errstr(status)), true); return; } periodic_startup_interval = lpcfg_parm_int(task->lp_ctx, NULL, "dreplsrv", "periodic_startup_interval", 15); /* in seconds */ service->periodic.interval = lpcfg_parm_int(task->lp_ctx, NULL, "dreplsrv", "periodic_interval", 300); /* in seconds */ status = dreplsrv_periodic_schedule(service, periodic_startup_interval); if (!W_ERROR_IS_OK(status)) { task_server_terminate(task, talloc_asprintf(task, "dreplsrv: Failed to periodic schedule: %s\n", win_errstr(status)), true); return; } service->pending.im = tevent_create_immediate(service); if (service->pending.im == NULL) { task_server_terminate(task, "dreplsrv: Failed to create immediate " "task for future DsReplicaSync\n", true); return; } /* if we are a RODC then we do not send DSReplicaSync*/ if (!service->am_rodc) { service->notify.interval = lpcfg_parm_int(task->lp_ctx, NULL, "dreplsrv", "notify_interval", 5); /* in seconds */ status = dreplsrv_notify_schedule(service, service->notify.interval); if (!W_ERROR_IS_OK(status)) { task_server_terminate(task, talloc_asprintf(task, "dreplsrv: Failed to setup notify schedule: %s\n", win_errstr(status)), true); return; } } irpc_add_name(task->msg_ctx, "dreplsrv"); IRPC_REGISTER(task->msg_ctx, irpc, DREPLSRV_REFRESH, dreplsrv_refresh, service); IRPC_REGISTER(task->msg_ctx, drsuapi, DRSUAPI_DSREPLICASYNC, drepl_replica_sync, service); IRPC_REGISTER(task->msg_ctx, drsuapi, DRSUAPI_DSREPLICAADD, dreplsrv_replica_add, service); IRPC_REGISTER(task->msg_ctx, drsuapi, DRSUAPI_DSREPLICADEL, dreplsrv_replica_del, service); IRPC_REGISTER(task->msg_ctx, drsuapi, DRSUAPI_DSREPLICAMOD, dreplsrv_replica_mod, service); IRPC_REGISTER(task->msg_ctx, irpc, DREPL_TAKEFSMOROLE, drepl_take_FSMO_role, service); IRPC_REGISTER(task->msg_ctx, irpc, DREPL_TRIGGER_REPL_SECRET, drepl_trigger_repl_secret, service); imessaging_register(task->msg_ctx, service, MSG_DREPL_ALLOCATE_RID, dreplsrv_allocate_rid); }
/* startup the kcc service task */ static void kccsrv_task_init(struct task_server *task) { WERROR status; struct kccsrv_service *service; uint32_t periodic_startup_interval; switch (lpcfg_server_role(task->lp_ctx)) { case ROLE_STANDALONE: task_server_terminate(task, "kccsrv: no KCC required in standalone configuration", false); return; case ROLE_DOMAIN_MEMBER: task_server_terminate(task, "kccsrv: no KCC required in domain member configuration", false); return; case ROLE_DOMAIN_CONTROLLER: /* Yes, we want a KCC */ break; } task_server_set_title(task, "task[kccsrv]"); service = talloc_zero(task, struct kccsrv_service); if (!service) { task_server_terminate(task, "kccsrv_task_init: out of memory", true); return; } service->task = task; service->startup_time = timeval_current(); task->private_data = service; status = kccsrv_init_creds(service); if (!W_ERROR_IS_OK(status)) { task_server_terminate(task, talloc_asprintf(task, "kccsrv: Failed to obtain server credentials: %s\n", win_errstr(status)), true); return; } status = kccsrv_connect_samdb(service, task->lp_ctx); if (!W_ERROR_IS_OK(status)) { task_server_terminate(task, talloc_asprintf(task, "kccsrv: Failed to connect to local samdb: %s\n", win_errstr(status)), true); return; } status = kccsrv_load_partitions(service); if (!W_ERROR_IS_OK(status)) { task_server_terminate(task, talloc_asprintf(task, "kccsrv: Failed to load partitions: %s\n", win_errstr(status)), true); return; } periodic_startup_interval = lpcfg_parm_int(task->lp_ctx, NULL, "kccsrv", "periodic_startup_interval", 15); /* in seconds */ service->periodic.interval = lpcfg_parm_int(task->lp_ctx, NULL, "kccsrv", "periodic_interval", 300); /* in seconds */ /* (kccsrv:samba_kcc=true) will run newer samba_kcc replication * topology generation code. */ service->samba_kcc_code = lpcfg_parm_bool(task->lp_ctx, NULL, "kccsrv", "samba_kcc", false); status = kccsrv_periodic_schedule(service, periodic_startup_interval); if (!W_ERROR_IS_OK(status)) { task_server_terminate(task, talloc_asprintf(task, "kccsrv: Failed to periodic schedule: %s\n", win_errstr(status)), true); return; } irpc_add_name(task->msg_ctx, "kccsrv"); IRPC_REGISTER(task->msg_ctx, drsuapi, DRSUAPI_DSEXECUTEKCC, kccsrv_execute_kcc, service); IRPC_REGISTER(task->msg_ctx, drsuapi, DRSUAPI_DSREPLICAGETINFO, kccsrv_replica_get_info, service); }