static int wins_ldb_init(struct ldb_module *module) { struct ldb_context *ldb = ldb_module_get_ctx(module); struct winsdb_handle *h; const char *owner; struct loadparm_context *lp_ctx = ldb_get_opaque(ldb, "loadparm"); ldb_module_set_private(module, NULL); owner = lpcfg_parm_string(lp_ctx, NULL, "winsdb", "local_owner"); if (!owner) { struct interface *ifaces; load_interface_list(module, lp_ctx, &ifaces); owner = iface_list_first_v4(ifaces); if (!owner) { owner = "0.0.0.0"; } } h = talloc_zero(module, struct winsdb_handle); if (!h) goto failed; h->ldb = ldb; h->caller = WINSDB_HANDLE_CALLER_ADMIN; h->local_owner = talloc_strdup(h, owner); if (!h->local_owner) goto failed; return ldb_set_opaque(ldb, "winsdb_handle", h); failed: talloc_free(h); return LDB_ERR_OTHER; }
/* 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"); }
/* 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 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"); }
/* 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"); }
/* main program */ int main(int argc, const char *argv[]) { bool ret = true; struct interface *ifaces; struct tevent_context *ev; poptContext pc; int opt; enum { OPT_BROADCAST_ADDRESS = 1000, OPT_UNICAST_ADDRESS, OPT_FIND_MASTER, OPT_WINS_LOOKUP, OPT_NODE_STATUS, OPT_ROOT_PORT, OPT_LOOKUP_BY_IP, OPT_CASE_SENSITIVE }; struct poptOption long_options[] = { POPT_AUTOHELP { "broadcast", 'B', POPT_ARG_STRING, NULL, OPT_BROADCAST_ADDRESS, "Specify address to use for broadcasts", "BROADCAST-ADDRESS" }, { "unicast", 'U', POPT_ARG_STRING, NULL, OPT_UNICAST_ADDRESS, "Specify address to use for unicast", NULL }, { "master-browser", 'M', POPT_ARG_NONE, NULL, OPT_FIND_MASTER, "Search for a master browser", NULL }, { "wins", 'W', POPT_ARG_NONE, NULL, OPT_WINS_LOOKUP, "Do a WINS lookup", NULL }, { "status", 'S', POPT_ARG_NONE, NULL, OPT_NODE_STATUS, "Lookup node status as well", NULL }, { "root-port", 'r', POPT_ARG_NONE, NULL, OPT_ROOT_PORT, "Use root port 137 (Win95 only replies to this)", NULL }, { "lookup-by-ip", 'A', POPT_ARG_NONE, NULL, OPT_LOOKUP_BY_IP, "Do a node status on <name> as an IP Address", NULL }, { "case-sensitive", 0, POPT_ARG_NONE, NULL, OPT_CASE_SENSITIVE, "Don't uppercase the name before sending", NULL }, POPT_COMMON_SAMBA { 0, 0, 0, 0 } }; pc = poptGetContext("nmblookup", argc, argv, long_options, POPT_CONTEXT_KEEP_FIRST); poptSetOtherOptionHelp(pc, "<NODE> ..."); while ((opt = poptGetNextOpt(pc)) != -1) { switch(opt) { case OPT_BROADCAST_ADDRESS: options.broadcast_address = poptGetOptArg(pc); break; case OPT_UNICAST_ADDRESS: options.unicast_address = poptGetOptArg(pc); break; case OPT_FIND_MASTER: options.find_master = true; break; case OPT_WINS_LOOKUP: options.wins_lookup = true; break; case OPT_NODE_STATUS: options.node_status = true; break; case OPT_ROOT_PORT: options.root_port = true; break; case OPT_LOOKUP_BY_IP: options.lookup_by_ip = true; break; case OPT_CASE_SENSITIVE: options.case_sensitive = true; break; } } /* swallow argv[0] */ poptGetArg(pc); if(!poptPeekArg(pc)) { poptPrintUsage(pc, stderr, 0); exit(1); } load_interface_list(NULL, cmdline_lp_ctx, &ifaces); ev = s4_event_context_init(talloc_autofree_context()); while (poptPeekArg(pc)) { const char *name = poptGetArg(pc); ret &= process_one(cmdline_lp_ctx, ev, ifaces, name, lpcfg_nbt_port(cmdline_lp_ctx)); } talloc_free(ev); talloc_free(ifaces); poptFreeContext(pc); if (!ret) { return 1; } return 0; }
/* fill in the cldap netlogon union for a given version */ NTSTATUS fill_netlogon_samlogon_response(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx, const char *domain, const char *netbios_domain, struct dom_sid *domain_sid, const char *domain_guid, const char *user, uint32_t acct_control, const char *src_address, uint32_t version, struct loadparm_context *lp_ctx, struct netlogon_samlogon_response *netlogon, bool fill_on_blank_request) { const char *dom_attrs[] = {"objectGUID", NULL}; const char *none_attrs[] = {NULL}; struct ldb_result *dom_res = NULL, *user_res = NULL; int ret; const char **services = lpcfg_server_services(lp_ctx); uint32_t server_type; const char *pdc_name; struct GUID domain_uuid; const char *dns_domain; const char *forest_domain; const char *pdc_dns_name; const char *flatname; const char *server_site; const char *client_site; const char *pdc_ip; struct ldb_dn *domain_dn = NULL; struct interface *ifaces; bool user_known, am_rodc; NTSTATUS status; /* the domain parameter could have an optional trailing "." */ if (domain && domain[strlen(domain)-1] == '.') { domain = talloc_strndup(mem_ctx, domain, strlen(domain)-1); NT_STATUS_HAVE_NO_MEMORY(domain); } /* Lookup using long or short domainname */ if (domain && (strcasecmp_m(domain, lpcfg_dnsdomain(lp_ctx)) == 0)) { domain_dn = ldb_get_default_basedn(sam_ctx); } if (netbios_domain && (strcasecmp_m(netbios_domain, lpcfg_sam_name(lp_ctx)) == 0)) { domain_dn = ldb_get_default_basedn(sam_ctx); } if (domain_dn) { const char *domain_identifier = domain != NULL ? domain : netbios_domain; ret = ldb_search(sam_ctx, mem_ctx, &dom_res, domain_dn, LDB_SCOPE_BASE, dom_attrs, "objectClass=domain"); if (ret != LDB_SUCCESS) { DEBUG(2,("Error finding domain '%s'/'%s' in sam: %s\n", domain_identifier, ldb_dn_get_linearized(domain_dn), ldb_errstring(sam_ctx))); return NT_STATUS_NO_SUCH_DOMAIN; } if (dom_res->count != 1) { DEBUG(2,("Error finding domain '%s'/'%s' in sam\n", domain_identifier, ldb_dn_get_linearized(domain_dn))); return NT_STATUS_NO_SUCH_DOMAIN; } } /* Lookup using GUID or SID */ if ((dom_res == NULL) && (domain_guid || domain_sid)) { if (domain_guid) { struct GUID binary_guid; struct ldb_val guid_val; /* By this means, we ensure we don't have funny stuff in the GUID */ status = GUID_from_string(domain_guid, &binary_guid); if (!NT_STATUS_IS_OK(status)) { return status; } /* And this gets the result into the binary format we want anyway */ status = GUID_to_ndr_blob(&binary_guid, mem_ctx, &guid_val); if (!NT_STATUS_IS_OK(status)) { return status; } ret = ldb_search(sam_ctx, mem_ctx, &dom_res, NULL, LDB_SCOPE_SUBTREE, dom_attrs, "(&(objectCategory=DomainDNS)(objectGUID=%s))", ldb_binary_encode(mem_ctx, guid_val)); } else { /* domain_sid case */ ret = ldb_search(sam_ctx, mem_ctx, &dom_res, NULL, LDB_SCOPE_SUBTREE, dom_attrs, "(&(objectCategory=DomainDNS)(objectSid=%s))", dom_sid_string(mem_ctx, domain_sid)); } if (ret != LDB_SUCCESS) { DEBUG(2,("Unable to find a correct reference to GUID '%s' or SID '%s' in sam: %s\n", domain_guid, dom_sid_string(mem_ctx, domain_sid), ldb_errstring(sam_ctx))); return NT_STATUS_NO_SUCH_DOMAIN; } else if (dom_res->count == 1) { /* Ok, now just check it is our domain */ if (ldb_dn_compare(ldb_get_default_basedn(sam_ctx), dom_res->msgs[0]->dn) != 0) { DEBUG(2,("The GUID '%s' or SID '%s' doesn't identify our domain\n", domain_guid, dom_sid_string(mem_ctx, domain_sid))); return NT_STATUS_NO_SUCH_DOMAIN; } } else { DEBUG(2,("Unable to find a correct reference to GUID '%s' or SID '%s' in sam\n", domain_guid, dom_sid_string(mem_ctx, domain_sid))); return NT_STATUS_NO_SUCH_DOMAIN; } } if (dom_res == NULL && fill_on_blank_request) { /* blank inputs gives our domain - tested against w2k8r2. Without this ADUC on Win7 won't start */ domain_dn = ldb_get_default_basedn(sam_ctx); ret = ldb_search(sam_ctx, mem_ctx, &dom_res, domain_dn, LDB_SCOPE_BASE, dom_attrs, "objectClass=domain"); if (ret != LDB_SUCCESS) { DEBUG(2,("Error finding domain '%s'/'%s' in sam: %s\n", lpcfg_dnsdomain(lp_ctx), ldb_dn_get_linearized(domain_dn), ldb_errstring(sam_ctx))); return NT_STATUS_NO_SUCH_DOMAIN; } } if (dom_res == NULL) { DEBUG(2,(__location__ ": Unable to get domain information with no inputs\n")); return NT_STATUS_NO_SUCH_DOMAIN; } /* work around different inputs for not-specified users */ if (!user) { user = ""; } /* Enquire about any valid username with just a CLDAP packet - * if kerberos didn't also do this, the security folks would * scream... */ if (user[0]) { \ /* Only allow some bits to be enquired: [MS-ATDS] 7.3.3.2 */ if (acct_control == (uint32_t)-1) { acct_control = 0; } acct_control = acct_control & (ACB_TEMPDUP | ACB_NORMAL | ACB_DOMTRUST | ACB_WSTRUST | ACB_SVRTRUST); /* We must exclude disabled accounts, but otherwise do the bitwise match the client asked for */ ret = ldb_search(sam_ctx, mem_ctx, &user_res, dom_res->msgs[0]->dn, LDB_SCOPE_SUBTREE, none_attrs, "(&(objectClass=user)(samAccountName=%s)" "(!(userAccountControl:" LDB_OID_COMPARATOR_AND ":=%u))" "(userAccountControl:" LDB_OID_COMPARATOR_OR ":=%u))", ldb_binary_encode_string(mem_ctx, user), UF_ACCOUNTDISABLE, ds_acb2uf(acct_control)); if (ret != LDB_SUCCESS) { DEBUG(2,("Unable to find reference to user '%s' with ACB 0x%8x under %s: %s\n", user, acct_control, ldb_dn_get_linearized(dom_res->msgs[0]->dn), ldb_errstring(sam_ctx))); return NT_STATUS_NO_SUCH_USER; } else if (user_res->count == 1) { user_known = true; } else { user_known = false; } } else { user_known = true; } server_type = DS_SERVER_DS | DS_SERVER_TIMESERV | DS_SERVER_GOOD_TIMESERV; if (samdb_is_pdc(sam_ctx)) { server_type |= DS_SERVER_PDC; } if (dsdb_functional_level(sam_ctx) >= DS_DOMAIN_FUNCTION_2008) { server_type |= DS_SERVER_FULL_SECRET_DOMAIN_6; } if (samdb_is_gc(sam_ctx)) { server_type |= DS_SERVER_GC; } if (str_list_check(services, "ldap")) { server_type |= DS_SERVER_LDAP; } if (str_list_check(services, "kdc")) { server_type |= DS_SERVER_KDC; } if (samdb_rodc(sam_ctx, &am_rodc) == LDB_SUCCESS && !am_rodc) { server_type |= DS_SERVER_WRITABLE; } pdc_name = talloc_asprintf(mem_ctx, "\\\\%s", lpcfg_netbios_name(lp_ctx)); NT_STATUS_HAVE_NO_MEMORY(pdc_name); domain_uuid = samdb_result_guid(dom_res->msgs[0], "objectGUID"); dns_domain = lpcfg_dnsdomain(lp_ctx); forest_domain = samdb_forest_name(sam_ctx, mem_ctx); NT_STATUS_HAVE_NO_MEMORY(forest_domain); pdc_dns_name = talloc_asprintf(mem_ctx, "%s.%s", strlower_talloc(mem_ctx, lpcfg_netbios_name(lp_ctx)), dns_domain); NT_STATUS_HAVE_NO_MEMORY(pdc_dns_name); flatname = lpcfg_workgroup(lp_ctx); server_site = samdb_server_site_name(sam_ctx, mem_ctx); NT_STATUS_HAVE_NO_MEMORY(server_site); client_site = samdb_client_site_name(sam_ctx, mem_ctx, src_address, NULL); NT_STATUS_HAVE_NO_MEMORY(client_site); if (strcasecmp(server_site, client_site) == 0) { server_type |= DS_SERVER_CLOSEST; } load_interface_list(mem_ctx, lp_ctx, &ifaces); if (src_address) { pdc_ip = iface_list_best_ip(ifaces, src_address); } else { pdc_ip = iface_list_first_v4(ifaces); } if (pdc_ip == NULL || !is_ipaddress_v4(pdc_ip)) { /* this matches windows behaviour */ pdc_ip = "127.0.0.1"; } ZERO_STRUCTP(netlogon); /* check if either of these bits is present */ if (version & (NETLOGON_NT_VERSION_5EX|NETLOGON_NT_VERSION_5EX_WITH_IP)) { uint32_t extra_flags = 0; netlogon->ntver = NETLOGON_NT_VERSION_5EX; /* could check if the user exists */ if (user_known) { netlogon->data.nt5_ex.command = LOGON_SAM_LOGON_RESPONSE_EX; } else { netlogon->data.nt5_ex.command = LOGON_SAM_LOGON_USER_UNKNOWN_EX; } netlogon->data.nt5_ex.pdc_name = pdc_name; netlogon->data.nt5_ex.user_name = user; netlogon->data.nt5_ex.domain_name = flatname; netlogon->data.nt5_ex.domain_uuid = domain_uuid; netlogon->data.nt5_ex.forest = forest_domain; netlogon->data.nt5_ex.dns_domain = dns_domain; netlogon->data.nt5_ex.pdc_dns_name = pdc_dns_name; netlogon->data.nt5_ex.server_site = server_site; netlogon->data.nt5_ex.client_site = client_site; if (version & NETLOGON_NT_VERSION_5EX_WITH_IP) { /* note that this is always a IPV4 address */ extra_flags = NETLOGON_NT_VERSION_5EX_WITH_IP; netlogon->data.nt5_ex.sockaddr.sockaddr_family = 2; netlogon->data.nt5_ex.sockaddr.pdc_ip = pdc_ip; netlogon->data.nt5_ex.sockaddr.remaining = data_blob_talloc_zero(mem_ctx, 8); } netlogon->data.nt5_ex.server_type = server_type; netlogon->data.nt5_ex.nt_version = NETLOGON_NT_VERSION_1|NETLOGON_NT_VERSION_5EX|extra_flags; netlogon->data.nt5_ex.lmnt_token = 0xFFFF; netlogon->data.nt5_ex.lm20_token = 0xFFFF; } else if (version & NETLOGON_NT_VERSION_5) { netlogon->ntver = NETLOGON_NT_VERSION_5; /* could check if the user exists */ if (user_known) { netlogon->data.nt5.command = LOGON_SAM_LOGON_RESPONSE; } else { netlogon->data.nt5.command = LOGON_SAM_LOGON_USER_UNKNOWN; } netlogon->data.nt5.pdc_name = pdc_name; netlogon->data.nt5.user_name = user; netlogon->data.nt5.domain_name = flatname; netlogon->data.nt5.domain_uuid = domain_uuid; netlogon->data.nt5.forest = forest_domain; netlogon->data.nt5.dns_domain = dns_domain; netlogon->data.nt5.pdc_dns_name = pdc_dns_name; netlogon->data.nt5.pdc_ip = pdc_ip; netlogon->data.nt5.server_type = server_type; netlogon->data.nt5.nt_version = NETLOGON_NT_VERSION_1|NETLOGON_NT_VERSION_5; netlogon->data.nt5.lmnt_token = 0xFFFF; netlogon->data.nt5.lm20_token = 0xFFFF; } else /* (version & NETLOGON_NT_VERSION_1) and all other cases */ { netlogon->ntver = NETLOGON_NT_VERSION_1; /* could check if the user exists */ if (user_known) { netlogon->data.nt4.command = LOGON_SAM_LOGON_RESPONSE; } else { netlogon->data.nt4.command = LOGON_SAM_LOGON_USER_UNKNOWN; } netlogon->data.nt4.pdc_name = pdc_name; netlogon->data.nt4.user_name = user; netlogon->data.nt4.domain_name = flatname; netlogon->data.nt4.nt_version = NETLOGON_NT_VERSION_1; netlogon->data.nt4.lmnt_token = 0xFFFF; netlogon->data.nt4.lm20_token = 0xFFFF; } return NT_STATUS_OK; }
/* return the list of interface IPs we have configured takes an loadparm context, returns a list of IPs in string form Does not return addresses on 127.0.0.0/8 */ static PyObject *py_interface_ips(PyObject *self, PyObject *args) { PyObject *pylist; int count; TALLOC_CTX *tmp_ctx; PyObject *py_lp_ctx; struct loadparm_context *lp_ctx; struct interface *ifaces; int i, ifcount; int all_interfaces = 1; if (!PyArg_ParseTuple(args, "O|i", &py_lp_ctx, &all_interfaces)) return NULL; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { PyErr_NoMemory(); return NULL; } lp_ctx = lpcfg_from_py_object(tmp_ctx, py_lp_ctx); if (lp_ctx == NULL) { talloc_free(tmp_ctx); return NULL; } load_interface_list(tmp_ctx, lp_ctx, &ifaces); count = iface_list_count(ifaces); /* first count how many are not loopback addresses */ for (ifcount = i = 0; i<count; i++) { const char *ip = iface_list_n_ip(ifaces, i); if (all_interfaces) { ifcount++; continue; } if (iface_list_same_net(ip, "127.0.0.1", "255.0.0.0")) { continue; } if (iface_list_same_net(ip, "169.254.0.0", "255.255.0.0")) { continue; } if (iface_list_same_net(ip, "::1", "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")) { continue; } if (iface_list_same_net(ip, "fe80::", "ffff:ffff:ffff:ffff::")) { continue; } ifcount++; } pylist = PyList_New(ifcount); for (ifcount = i = 0; i<count; i++) { const char *ip = iface_list_n_ip(ifaces, i); if (all_interfaces) { PyList_SetItem(pylist, ifcount, PyString_FromString(ip)); ifcount++; continue; } if (iface_list_same_net(ip, "127.0.0.1", "255.0.0.0")) { continue; } if (iface_list_same_net(ip, "169.254.0.0", "255.255.0.0")) { continue; } if (iface_list_same_net(ip, "::1", "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")) { continue; } if (iface_list_same_net(ip, "fe80::", "ffff:ffff:ffff:ffff::")) { continue; } PyList_SetItem(pylist, ifcount, PyString_FromString(ip)); ifcount++; } talloc_free(tmp_ctx); return pylist; }
/* test UDP/138 netlogon requests */ static bool nbt_test_netlogon(struct torture_context *tctx) { struct dgram_mailslot_handler *dgmslot; struct nbt_dgram_socket *dgmsock = nbt_dgram_socket_init(tctx, tctx->ev); struct socket_address *dest; const char *myaddress; struct nbt_netlogon_packet logon; struct nbt_netlogon_response *response; struct nbt_name myname; NTSTATUS status; struct timeval tv = timeval_current(); struct socket_address *socket_address; const char *address; struct nbt_name name; struct interface *ifaces; name.name = lpcfg_workgroup(tctx->lp_ctx); name.type = NBT_NAME_LOGON; name.scope = NULL; /* do an initial name resolution to find its IP */ torture_assert_ntstatus_ok(tctx, resolve_name_ex(lpcfg_resolve_context(tctx->lp_ctx), 0, 0, &name, tctx, &address, tctx->ev), talloc_asprintf(tctx, "Failed to resolve %s", name.name)); load_interface_list(tctx, tctx->lp_ctx, &ifaces); myaddress = talloc_strdup(dgmsock, iface_list_best_ip(ifaces, address)); socket_address = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name, myaddress, lpcfg_dgram_port(tctx->lp_ctx)); torture_assert(tctx, socket_address != NULL, "Error getting address"); /* try receiving replies on port 138 first, which will only work if we are root and smbd/nmbd are not running - fall back to listening on any port, which means replies from most windows versions won't be seen */ status = socket_listen(dgmsock->sock, socket_address, 0, 0); if (!NT_STATUS_IS_OK(status)) { talloc_free(socket_address); socket_address = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name, myaddress, 0); torture_assert(tctx, socket_address != NULL, "Error getting address"); socket_listen(dgmsock->sock, socket_address, 0, 0); } /* setup a temporary mailslot listener for replies */ dgmslot = dgram_mailslot_temp(dgmsock, NBT_MAILSLOT_GETDC, netlogon_handler, NULL); torture_assert(tctx, dgmslot != NULL, "Error temporary mailslot for GetDC"); ZERO_STRUCT(logon); logon.command = LOGON_PRIMARY_QUERY; logon.req.pdc.computer_name = TEST_NAME; logon.req.pdc.mailslot_name = dgmslot->mailslot_name; logon.req.pdc.unicode_name = TEST_NAME; logon.req.pdc.nt_version = 1; logon.req.pdc.lmnt_token = 0xFFFF; logon.req.pdc.lm20_token = 0xFFFF; make_nbt_name_client(&myname, TEST_NAME); dest = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name, address, lpcfg_dgram_port(tctx->lp_ctx)); torture_assert(tctx, dest != NULL, "Error getting address"); status = dgram_mailslot_netlogon_send(dgmsock, &name, dest, NBT_MAILSLOT_NETLOGON, &myname, &logon); torture_assert_ntstatus_ok(tctx, status, "Failed to send netlogon request"); while (timeval_elapsed(&tv) < 5 && !dgmslot->private_data) { tevent_loop_once(dgmsock->event_ctx); } response = talloc_get_type(dgmslot->private_data, struct nbt_netlogon_response); torture_assert(tctx, response != NULL, "Failed to receive a netlogon reply packet"); torture_assert(tctx, response->response_type == NETLOGON_GET_PDC, "Got incorrect type of netlogon response"); torture_assert(tctx, response->data.get_pdc.command == NETLOGON_RESPONSE_FROM_PDC, "Got incorrect netlogon response command"); return true; }
/* test UDP/138 ntlogon requests */ static bool nbt_test_ntlogon(struct torture_context *tctx) { struct dgram_mailslot_handler *dgmslot; struct nbt_dgram_socket *dgmsock = nbt_dgram_socket_init(tctx, tctx->ev); struct socket_address *dest; struct test_join *join_ctx; const struct dom_sid *dom_sid; struct cli_credentials *machine_credentials; const char *myaddress; struct nbt_netlogon_packet logon; struct nbt_netlogon_response *response; struct nbt_name myname; NTSTATUS status; struct timeval tv = timeval_current(); struct socket_address *socket_address; const char *address; struct nbt_name name; struct interface *ifaces; name.name = lpcfg_workgroup(tctx->lp_ctx); name.type = NBT_NAME_LOGON; name.scope = NULL; /* do an initial name resolution to find its IP */ torture_assert_ntstatus_ok(tctx, resolve_name_ex(lpcfg_resolve_context(tctx->lp_ctx), 0, 0, &name, tctx, &address, tctx->ev), talloc_asprintf(tctx, "Failed to resolve %s", name.name)); load_interface_list(tctx, tctx->lp_ctx, &ifaces); myaddress = talloc_strdup(dgmsock, iface_list_best_ip(ifaces, address)); socket_address = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name, myaddress, lpcfg_dgram_port(tctx->lp_ctx)); torture_assert(tctx, socket_address != NULL, "Error getting address"); /* try receiving replies on port 138 first, which will only work if we are root and smbd/nmbd are not running - fall back to listening on any port, which means replies from most windows versions won't be seen */ status = socket_listen(dgmsock->sock, socket_address, 0, 0); if (!NT_STATUS_IS_OK(status)) { talloc_free(socket_address); socket_address = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name, myaddress, 0); torture_assert(tctx, socket_address != NULL, "Error getting address"); socket_listen(dgmsock->sock, socket_address, 0, 0); } join_ctx = torture_join_domain(tctx, TEST_NAME, ACB_WSTRUST, &machine_credentials); torture_assert(tctx, join_ctx != NULL, talloc_asprintf(tctx, "Failed to join domain %s as %s\n", lpcfg_workgroup(tctx->lp_ctx), TEST_NAME)); dom_sid = torture_join_sid(join_ctx); /* setup a temporary mailslot listener for replies */ dgmslot = dgram_mailslot_temp(dgmsock, NBT_MAILSLOT_GETDC, netlogon_handler, NULL); torture_assert(tctx, dgmslot != NULL, "Error temporary mailslot for GetDC"); ZERO_STRUCT(logon); logon.command = LOGON_SAM_LOGON_REQUEST; logon.req.logon.request_count = 0; logon.req.logon.computer_name = TEST_NAME; logon.req.logon.user_name = TEST_NAME"$"; logon.req.logon.mailslot_name = dgmslot->mailslot_name; logon.req.logon.acct_control = ACB_WSTRUST; /* Try with a SID this time */ logon.req.logon.sid = *dom_sid; logon.req.logon.nt_version = 1; logon.req.logon.lmnt_token = 0xFFFF; logon.req.logon.lm20_token = 0xFFFF; make_nbt_name_client(&myname, TEST_NAME); dest = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name, address, lpcfg_dgram_port(tctx->lp_ctx)); torture_assert(tctx, dest != NULL, "Error getting address"); status = dgram_mailslot_netlogon_send(dgmsock, &name, dest, NBT_MAILSLOT_NTLOGON, &myname, &logon); torture_assert_ntstatus_ok(tctx, status, "Failed to send ntlogon request"); while (timeval_elapsed(&tv) < 5 && dgmslot->private_data == NULL) { tevent_loop_once(dgmsock->event_ctx); } response = talloc_get_type(dgmslot->private_data, struct nbt_netlogon_response); torture_assert(tctx, response != NULL, "Failed to receive a netlogon reply packet"); torture_assert_int_equal(tctx, response->response_type, NETLOGON_SAMLOGON, "Got incorrect type of netlogon response"); map_netlogon_samlogon_response(&response->data.samlogon); torture_assert_int_equal(tctx, response->data.samlogon.data.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE, "Got incorrect netlogon response command"); torture_assert_str_equal(tctx, response->data.samlogon.data.nt5_ex.user_name, TEST_NAME"$", "Got incorrect user in netlogon response"); torture_assert(tctx, strstr(response->data.samlogon.data.nt5_ex.pdc_name, "\\\\") != NULL, "PDC name should be in UNC form"); /* setup a temporary mailslot listener for replies */ dgmslot = dgram_mailslot_temp(dgmsock, NBT_MAILSLOT_GETDC, netlogon_handler, NULL); torture_assert(tctx, dgmslot != NULL, "Error temporary mailslot for GetDC"); ZERO_STRUCT(logon); logon.command = LOGON_SAM_LOGON_REQUEST; logon.req.logon.request_count = 0; logon.req.logon.computer_name = TEST_NAME; logon.req.logon.user_name = TEST_NAME"$"; logon.req.logon.mailslot_name = dgmslot->mailslot_name; logon.req.logon.acct_control = ACB_WSTRUST; /* Leave sid as all zero */ logon.req.logon.nt_version = 1; logon.req.logon.lmnt_token = 0xFFFF; logon.req.logon.lm20_token = 0xFFFF; make_nbt_name_client(&myname, TEST_NAME); dest = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name, address, lpcfg_dgram_port(tctx->lp_ctx)); torture_assert(tctx, dest != NULL, "Error getting address"); status = dgram_mailslot_netlogon_send(dgmsock, &name, dest, NBT_MAILSLOT_NTLOGON, &myname, &logon); torture_assert_ntstatus_ok(tctx, status, "Failed to send ntlogon request"); while (timeval_elapsed(&tv) < 5 && dgmslot->private_data == NULL) { tevent_loop_once(dgmsock->event_ctx); } response = talloc_get_type(dgmslot->private_data, struct nbt_netlogon_response); torture_assert(tctx, response != NULL, "Failed to receive a netlogon reply packet"); torture_assert_int_equal(tctx, response->response_type, NETLOGON_SAMLOGON, "Got incorrect type of netlogon response"); map_netlogon_samlogon_response(&response->data.samlogon); torture_assert_int_equal(tctx, response->data.samlogon.data.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE, "Got incorrect netlogon response command"); torture_assert_str_equal(tctx, response->data.samlogon.data.nt5_ex.user_name, TEST_NAME"$", "Got incorrect user in netlogon response"); torture_assert(tctx, strstr(response->data.samlogon.data.nt5_ex.pdc_name, "\\\\") != NULL, "PDC name should be in UNC form"); /* setup (another) temporary mailslot listener for replies */ dgmslot = dgram_mailslot_temp(dgmsock, NBT_MAILSLOT_GETDC, netlogon_handler, NULL); torture_assert(tctx, dgmslot != NULL, "Error temporary mailslot for GetDC"); ZERO_STRUCT(logon); logon.command = LOGON_PRIMARY_QUERY; logon.req.pdc.computer_name = TEST_NAME; logon.req.pdc.mailslot_name = dgmslot->mailslot_name; logon.req.pdc.unicode_name = TEST_NAME; logon.req.pdc.nt_version = 1; logon.req.pdc.lmnt_token = 0xFFFF; logon.req.pdc.lm20_token = 0xFFFF; make_nbt_name_client(&myname, TEST_NAME); dest = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name, address, lpcfg_dgram_port(tctx->lp_ctx)); torture_assert(tctx, dest != NULL, "Error getting address"); status = dgram_mailslot_netlogon_send(dgmsock, &name, dest, NBT_MAILSLOT_NTLOGON, &myname, &logon); torture_assert_ntstatus_ok(tctx, status, "Failed to send ntlogon request"); while (timeval_elapsed(&tv) < 5 && !dgmslot->private_data) { tevent_loop_once(dgmsock->event_ctx); } response = talloc_get_type(dgmslot->private_data, struct nbt_netlogon_response); torture_assert(tctx, response != NULL, "Failed to receive a netlogon reply packet"); torture_assert_int_equal(tctx, response->response_type, NETLOGON_GET_PDC, "Got incorrect type of ntlogon response"); torture_assert_int_equal(tctx, response->data.get_pdc.command, NETLOGON_RESPONSE_FROM_PDC, "Got incorrect ntlogon response command"); torture_leave_domain(tctx, join_ctx); /* setup (another) temporary mailslot listener for replies */ dgmslot = dgram_mailslot_temp(dgmsock, NBT_MAILSLOT_GETDC, netlogon_handler, NULL); torture_assert(tctx, dgmslot != NULL, "Error temporary mailslot for GetDC"); ZERO_STRUCT(logon); logon.command = LOGON_PRIMARY_QUERY; logon.req.pdc.computer_name = TEST_NAME; logon.req.pdc.mailslot_name = dgmslot->mailslot_name; logon.req.pdc.unicode_name = TEST_NAME; logon.req.pdc.nt_version = 1; logon.req.pdc.lmnt_token = 0xFFFF; logon.req.pdc.lm20_token = 0xFFFF; make_nbt_name_client(&myname, TEST_NAME); dest = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name, address, lpcfg_dgram_port(tctx->lp_ctx)); torture_assert(tctx, dest != NULL, "Error getting address"); status = dgram_mailslot_netlogon_send(dgmsock, &name, dest, NBT_MAILSLOT_NTLOGON, &myname, &logon); torture_assert_ntstatus_ok(tctx, status, "Failed to send ntlogon request"); while (timeval_elapsed(&tv) < 5 && !dgmslot->private_data) { tevent_loop_once(dgmsock->event_ctx); } response = talloc_get_type(dgmslot->private_data, struct nbt_netlogon_response); torture_assert(tctx, response != NULL, "Failed to receive a netlogon reply packet"); torture_assert_int_equal(tctx, response->response_type, NETLOGON_GET_PDC, "Got incorrect type of ntlogon response"); torture_assert_int_equal(tctx, response->data.get_pdc.command, NETLOGON_RESPONSE_FROM_PDC, "Got incorrect ntlogon response command"); return 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; }
struct dnsserver_serverinfo *dnsserver_init_serverinfo(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx, struct ldb_context *samdb) { struct dnsserver_serverinfo *serverinfo; struct dcerpc_server_info *dinfo; struct ldb_dn *domain_dn, *forest_dn; struct interface *ifaces; int num_interfaces, i; serverinfo = talloc_zero(mem_ctx, struct dnsserver_serverinfo); if (serverinfo == NULL) { return NULL; } dinfo = lpcfg_dcerpc_server_info(mem_ctx, lp_ctx); if (dinfo) { serverinfo->dwVersion = (dinfo->version_build & 0x0000FFFF) << 16 | (dinfo->version_minor & 0x000000FF) << 8 | (dinfo->version_major & 0x000000FF); talloc_free(dinfo); } else { serverinfo->dwVersion = 0x0ECE0205; /* build, os_minor, os_major */; } serverinfo->fBootMethod = DNS_BOOT_METHOD_DIRECTORY; serverinfo->fAdminConfigured = 0; serverinfo->fAllowUpdate = 1; serverinfo->fDsAvailable = 1; serverinfo->pszServerName = talloc_asprintf(mem_ctx, "%s.%s", lpcfg_netbios_name(lp_ctx), lpcfg_dnsdomain(lp_ctx)); domain_dn = ldb_get_default_basedn(samdb); forest_dn = ldb_get_root_basedn(samdb); serverinfo->pszDsContainer = talloc_asprintf(mem_ctx, "CN=MicrosoftDNS,DC=DomainDnsZones,%s", ldb_dn_get_linearized(domain_dn)); serverinfo->dwDsForestVersion = dsdb_forest_functional_level(samdb); serverinfo->dwDsDomainVersion = dsdb_functional_level(samdb); serverinfo->dwDsDsaVersion = 4; /* need to do ldb search here */ serverinfo->pszDomainName = samdb_dn_to_dns_domain(mem_ctx, domain_dn); serverinfo->pszForestName = samdb_dn_to_dns_domain(mem_ctx, forest_dn); serverinfo->pszDomainDirectoryPartition = talloc_asprintf(mem_ctx, "DC=DomainDnsZones,%s", ldb_dn_get_linearized(domain_dn)); serverinfo->pszForestDirectoryPartition = talloc_asprintf(mem_ctx, "DC=ForestDnsZones,%s", ldb_dn_get_linearized(forest_dn)); load_interface_list(mem_ctx, lp_ctx, &ifaces); num_interfaces = iface_list_count(ifaces); serverinfo->aipServerAddrs = talloc_zero(mem_ctx, struct IP4_ARRAY); if (serverinfo->aipServerAddrs) { serverinfo->aipServerAddrs->AddrCount = num_interfaces; if (num_interfaces > 0) { serverinfo->aipServerAddrs->AddrArray = talloc_zero_array(mem_ctx, unsigned int, num_interfaces); if (serverinfo->aipServerAddrs->AddrArray) { for (i=0; i<num_interfaces; i++) { serverinfo->aipServerAddrs->AddrArray[i] = inet_addr(iface_list_n_ip(ifaces, i)); } } else { serverinfo->aipServerAddrs->AddrCount = 0; } }
/* startup the web server task */ static void websrv_task_init(struct task_server *task) { NTSTATUS status; uint16_t port = lpcfg_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("single"); if (!model_ops) goto failed; /* startup the Python 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; wdata->task = task; task->private_data = wdata; if (lpcfg_interfaces(task->lp_ctx) && lpcfg_bind_interfaces_only(task->lp_ctx)) { int num_interfaces; int i; struct interface *ifaces; load_interface_list(NULL, task->lp_ctx, &ifaces); num_interfaces = iface_list_count(ifaces); for(i = 0; i < num_interfaces; i++) { const char *address = iface_list_n_ip(ifaces, i); status = stream_setup_socket(task, task->event_ctx, task->lp_ctx, model_ops, &web_stream_ops, "ip", address, &port, lpcfg_socket_options(task->lp_ctx), task); if (!NT_STATUS_IS_OK(status)) goto failed; } talloc_free(ifaces); } else { char **wcard; int i; wcard = iface_list_wildcard(task); if (wcard == NULL) { DEBUG(0,("No wildcard addresses available\n")); goto failed; } for (i=0; wcard[i]; i++) { status = stream_setup_socket(task, task->event_ctx, task->lp_ctx, model_ops, &web_stream_ops, "ip", wcard[i], &port, lpcfg_socket_options(task->lp_ctx), wdata); if (!NT_STATUS_IS_OK(status)) goto failed; } talloc_free(wcard); } 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); }
/* test operations against a WINS server */ static bool nbt_test_wins_name(struct torture_context *tctx, const char *address, struct nbt_name *name, uint16_t nb_flags, bool try_low_port, uint8_t register_rcode) { struct nbt_name_register_wins io; struct nbt_name_register name_register; struct nbt_name_query query; struct nbt_name_refresh_wins refresh; struct nbt_name_release release; struct nbt_name_request *req; NTSTATUS status; struct nbt_name_socket *nbtsock = torture_init_nbt_socket(tctx); const char *myaddress; struct socket_address *socket_address; struct interface *ifaces; bool low_port = try_low_port; load_interface_list(tctx, tctx->lp_ctx, &ifaces); myaddress = talloc_strdup(tctx, iface_list_best_ip(ifaces, address)); socket_address = socket_address_from_strings(tctx, nbtsock->sock->backend_name, myaddress, lpcfg_nbt_port(tctx->lp_ctx)); torture_assert(tctx, socket_address != NULL, "Error getting address"); /* we do the listen here to ensure the WINS server receives the packets from the right IP */ status = socket_listen(nbtsock->sock, socket_address, 0, 0); talloc_free(socket_address); if (!NT_STATUS_IS_OK(status)) { low_port = false; socket_address = socket_address_from_strings(tctx, nbtsock->sock->backend_name, myaddress, 0); torture_assert(tctx, socket_address != NULL, "Error getting address"); status = socket_listen(nbtsock->sock, socket_address, 0, 0); talloc_free(socket_address); torture_assert_ntstatus_ok(tctx, status, "socket_listen for WINS failed"); } torture_comment(tctx, "Testing name registration to WINS with name %s at %s nb_flags=0x%x\n", nbt_name_string(tctx, name), myaddress, nb_flags); torture_comment(tctx, "release the name\n"); release.in.name = *name; release.in.dest_port = lpcfg_nbt_port(tctx->lp_ctx); release.in.dest_addr = address; release.in.address = myaddress; release.in.nb_flags = nb_flags; release.in.broadcast = false; release.in.timeout = 3; release.in.retries = 0; status = nbt_name_release(nbtsock, tctx, &release); torture_assert_ntstatus_ok(tctx, status, talloc_asprintf(tctx, "Bad response from %s for name query", address)); CHECK_VALUE(tctx, release.out.rcode, 0); if (nb_flags & NBT_NM_GROUP) { /* ignore this for group names */ } else if (!low_port) { torture_comment(tctx, "no low port - skip: register the name with a wrong address\n"); } else { torture_comment(tctx, "register the name with a wrong address (makes the next request slow!)\n"); io.in.name = *name; io.in.wins_port = lpcfg_nbt_port(tctx->lp_ctx); io.in.wins_servers = const_str_list( str_list_make_single(tctx, address)); io.in.addresses = const_str_list( str_list_make_single(tctx, "127.64.64.1")); io.in.nb_flags = nb_flags; io.in.ttl = 300000; status = nbt_name_register_wins(nbtsock, tctx, &io); if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) { torture_assert_ntstatus_ok(tctx, status, talloc_asprintf(tctx, "No response from %s for name register\n", address)); } torture_assert_ntstatus_ok(tctx, status, talloc_asprintf(tctx, "Bad response from %s for name register\n", address)); CHECK_STRING(tctx, io.out.wins_server, address); CHECK_VALUE(tctx, io.out.rcode, 0); torture_comment(tctx, "register the name correct address\n"); name_register.in.name = *name; name_register.in.dest_port = lpcfg_nbt_port(tctx->lp_ctx); name_register.in.dest_addr = address; name_register.in.address = myaddress; name_register.in.nb_flags = nb_flags; name_register.in.register_demand= false; name_register.in.broadcast = false; name_register.in.multi_homed = true; name_register.in.ttl = 300000; name_register.in.timeout = 3; name_register.in.retries = 2; /* * test if the server ignores resent requests */ req = nbt_name_register_send(nbtsock, &name_register); while (true) { event_loop_once(nbtsock->event_ctx); if (req->state != NBT_REQUEST_WAIT) { break; } if (req->received_wack) { /* * if we received the wack response * we resend the request and the * server should ignore that * and not handle it as new request */ req->state = NBT_REQUEST_SEND; DLIST_ADD_END(nbtsock->send_queue, req, struct nbt_name_request *); EVENT_FD_WRITEABLE(nbtsock->fde); break; } } status = nbt_name_register_recv(req, tctx, &name_register); if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) { torture_assert_ntstatus_ok(tctx, status, talloc_asprintf(tctx, "No response from %s for name register\n", address)); } torture_assert_ntstatus_ok(tctx, status, talloc_asprintf(tctx, "Bad response from %s for name register\n", address)); CHECK_VALUE(tctx, name_register.out.rcode, 0); CHECK_STRING(tctx, name_register.out.reply_addr, myaddress); }