/** * @brief Returns an absolute path to a file in the Samba private directory. * * @param name File to find, relative to PRIVATEDIR. * if name is not relative, then use it as-is * * @retval Pointer to a talloc'ed string containing the full path. **/ char *lpcfg_private_path(TALLOC_CTX* mem_ctx, struct loadparm_context *lp_ctx, const char *name) { char *fname; if (name == NULL) { return NULL; } if (name[0] == 0 || name[0] == '/' || strstr(name, ":/")) { return talloc_strdup(mem_ctx, name); } fname = talloc_asprintf(mem_ctx, "%s/%s", lpcfg_private_dir(lp_ctx), name); return fname; }
static PyObject *py_samdb_url(PyObject *self) { struct loadparm_context *lp_ctx = PyLoadparmContext_AsLoadparmContext(self); return PyString_FromFormat("tdb://%s/sam.ldb", lpcfg_private_dir(lp_ctx)); }
/* main server. */ static int binary_smbd_main(const char *binary_name, int argc, const char *argv[]) { bool opt_daemon = false; bool opt_interactive = false; int opt; poptContext pc; #define _MODULE_PROTO(init) extern NTSTATUS init(void); STATIC_service_MODULES_PROTO; init_module_fn static_init[] = { STATIC_service_MODULES }; init_module_fn *shared_init; struct tevent_context *event_ctx; uint16_t stdin_event_flags; NTSTATUS status; const char *model = "standard"; int max_runtime = 0; enum { OPT_DAEMON = 1000, OPT_INTERACTIVE, OPT_PROCESS_MODEL, OPT_SHOW_BUILD }; struct poptOption long_options[] = { POPT_AUTOHELP {"daemon", 'D', POPT_ARG_NONE, NULL, OPT_DAEMON, "Become a daemon (default)", NULL }, {"interactive", 'i', POPT_ARG_NONE, NULL, OPT_INTERACTIVE, "Run interactive (not a daemon)", NULL}, {"model", 'M', POPT_ARG_STRING, NULL, OPT_PROCESS_MODEL, "Select process model", "MODEL"}, {"maximum-runtime",0, POPT_ARG_INT, &max_runtime, 0, "set maximum runtime of the server process, till autotermination", "seconds"}, {"show-build", 'b', POPT_ARG_NONE, NULL, OPT_SHOW_BUILD, "show build info", NULL }, POPT_COMMON_SAMBA POPT_COMMON_VERSION { NULL } }; pc = poptGetContext(binary_name, argc, argv, long_options, 0); while((opt = poptGetNextOpt(pc)) != -1) { switch(opt) { case OPT_DAEMON: opt_daemon = true; break; case OPT_INTERACTIVE: opt_interactive = true; break; case OPT_PROCESS_MODEL: model = poptGetOptArg(pc); break; case OPT_SHOW_BUILD: show_build(); break; default: fprintf(stderr, "\nInvalid option %s: %s\n\n", poptBadOption(pc, 0), poptStrerror(opt)); poptPrintUsage(pc, stderr, 0); return 1; } } if (opt_daemon && opt_interactive) { fprintf(stderr,"\nERROR: " "Option -i|--interactive is not allowed together with -D|--daemon\n\n"); poptPrintUsage(pc, stderr, 0); return 1; } else if (!opt_interactive) { /* default is --daemon */ opt_daemon = true; } poptFreeContext(pc); setup_logging(binary_name, opt_interactive?DEBUG_STDOUT:DEBUG_FILE); setup_signals(); /* we want total control over the permissions on created files, so set our umask to 0 */ umask(0); DEBUG(0,("%s version %s started.\n", binary_name, SAMBA_VERSION_STRING)); DEBUGADD(0,("Copyright Andrew Tridgell and the Samba Team 1992-2011\n")); if (sizeof(uint16_t) < 2 || sizeof(uint32_t) < 4 || sizeof(uint64_t) < 8) { DEBUG(0,("ERROR: Samba is not configured correctly for the word size on your machine\n")); DEBUGADD(0,("sizeof(uint16_t) = %u, sizeof(uint32_t) %u, sizeof(uint64_t) = %u\n", (unsigned int)sizeof(uint16_t), (unsigned int)sizeof(uint32_t), (unsigned int)sizeof(uint64_t))); return 1; } if (opt_daemon) { DEBUG(3,("Becoming a daemon.\n")); become_daemon(true, false, false); } cleanup_tmp_files(cmdline_lp_ctx); if (!directory_exist(lpcfg_lockdir(cmdline_lp_ctx))) { mkdir(lpcfg_lockdir(cmdline_lp_ctx), 0755); } pidfile_create(lpcfg_piddir(cmdline_lp_ctx), binary_name); /* Set up a database to hold a random seed, in case we don't * have /dev/urandom */ if (!randseed_init(talloc_autofree_context(), cmdline_lp_ctx)) { return 1; } if (lpcfg_server_role(cmdline_lp_ctx) == ROLE_DOMAIN_CONTROLLER) { if (!open_schannel_session_store(talloc_autofree_context(), lpcfg_private_dir(cmdline_lp_ctx))) { DEBUG(0,("ERROR: Samba cannot open schannel store for secured NETLOGON operations.\n")); exit(1); } } gensec_init(); /* FIXME: */ ntptr_init(); /* FIXME: maybe run this in the initialization function of the spoolss RPC server instead? */ ntvfs_init(cmdline_lp_ctx); /* FIXME: maybe run this in the initialization functions of the SMB[,2] server instead? */ process_model_init(cmdline_lp_ctx); shared_init = load_samba_modules(NULL, "service"); run_init_functions(static_init); run_init_functions(shared_init); talloc_free(shared_init); /* the event context is the top level structure in smbd. Everything else should hang off that */ event_ctx = s4_event_context_init(talloc_autofree_context()); if (event_ctx == NULL) { DEBUG(0,("Initializing event context failed\n")); return 1; } if (opt_interactive) { /* terminate when stdin goes away */ stdin_event_flags = TEVENT_FD_READ; } else { /* stay alive forever */ stdin_event_flags = 0; } /* catch EOF on stdin */ #ifdef SIGTTIN signal(SIGTTIN, SIG_IGN); #endif tevent_add_fd(event_ctx, event_ctx, 0, stdin_event_flags, server_stdin_handler, discard_const(binary_name)); if (max_runtime) { DEBUG(0,("Called with maxruntime %d - current ts %llu\n", max_runtime, (unsigned long long) time(NULL))); tevent_add_timer(event_ctx, event_ctx, timeval_current_ofs(max_runtime, 0), max_runtime_handler, discard_const(binary_name)); } prime_ldb_databases(event_ctx); status = setup_parent_messaging(event_ctx, cmdline_lp_ctx); if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("Failed to setup parent messaging - %s\n", nt_errstr(status))); return 1; } DEBUG(0,("%s: using '%s' process model\n", binary_name, model)); status = server_service_startup(event_ctx, cmdline_lp_ctx, model, lpcfg_server_services(cmdline_lp_ctx)); if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("Starting Services failed - %s\n", nt_errstr(status))); return 1; } /* wait for events - this is where smbd sits for most of its life */ tevent_loop_wait(event_ctx); /* as everything hangs off this event context, freeing it should initiate a clean shutdown of all services */ talloc_free(event_ctx); return 0; }
/* authorize a zone update */ _PUBLIC_ isc_boolean_t dlz_ssumatch(const char *signer, const char *name, const char *tcpaddr, const char *type, const char *key, uint32_t keydatalen, uint8_t *keydata, void *dbdata) { struct dlz_bind9_data *state = talloc_get_type_abort(dbdata, struct dlz_bind9_data); TALLOC_CTX *tmp_ctx; DATA_BLOB ap_req; struct cli_credentials *server_credentials; char *keytab_name; int ret; int ldb_ret; NTSTATUS nt_status; struct gensec_security *gensec_ctx; struct auth_session_info *session_info; struct ldb_dn *dn; isc_result_t result; struct ldb_result *res; const char * attrs[] = { NULL }; uint32_t access_mask; /* Remove cached credentials, if any */ if (state->session_info) { talloc_free(state->session_info); state->session_info = NULL; } if (state->update_name) { talloc_free(state->update_name); state->update_name = NULL; } tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { state->log(ISC_LOG_ERROR, "samba_dlz: no memory"); return ISC_FALSE; } ap_req = data_blob_const(keydata, keydatalen); server_credentials = cli_credentials_init(tmp_ctx); if (!server_credentials) { state->log(ISC_LOG_ERROR, "samba_dlz: failed to init server credentials"); talloc_free(tmp_ctx); return ISC_FALSE; } cli_credentials_set_krb5_context(server_credentials, state->smb_krb5_ctx); cli_credentials_set_conf(server_credentials, state->lp); keytab_name = talloc_asprintf(tmp_ctx, "file:%s/dns.keytab", lpcfg_private_dir(state->lp)); ret = cli_credentials_set_keytab_name(server_credentials, state->lp, keytab_name, CRED_SPECIFIED); if (ret != 0) { state->log(ISC_LOG_ERROR, "samba_dlz: failed to obtain server credentials from %s", keytab_name); talloc_free(tmp_ctx); return ISC_FALSE; } talloc_free(keytab_name); nt_status = gensec_server_start(tmp_ctx, lpcfg_gensec_settings(tmp_ctx, state->lp), state->auth_context, &gensec_ctx); if (!NT_STATUS_IS_OK(nt_status)) { state->log(ISC_LOG_ERROR, "samba_dlz: failed to start gensec server"); talloc_free(tmp_ctx); return ISC_FALSE; } gensec_set_credentials(gensec_ctx, server_credentials); nt_status = gensec_start_mech_by_name(gensec_ctx, "spnego"); if (!NT_STATUS_IS_OK(nt_status)) { state->log(ISC_LOG_ERROR, "samba_dlz: failed to start spnego"); talloc_free(tmp_ctx); return ISC_FALSE; } nt_status = gensec_update(gensec_ctx, tmp_ctx, state->ev_ctx, ap_req, &ap_req); if (!NT_STATUS_IS_OK(nt_status)) { state->log(ISC_LOG_ERROR, "samba_dlz: spnego update failed"); talloc_free(tmp_ctx); return ISC_FALSE; } nt_status = gensec_session_info(gensec_ctx, tmp_ctx, &session_info); if (!NT_STATUS_IS_OK(nt_status)) { state->log(ISC_LOG_ERROR, "samba_dlz: failed to create session info"); talloc_free(tmp_ctx); return ISC_FALSE; } /* Get the DN from name */ result = b9_find_name_dn(state, name, tmp_ctx, &dn); if (result != ISC_R_SUCCESS) { state->log(ISC_LOG_ERROR, "samba_dlz: failed to find name %s", name); talloc_free(tmp_ctx); return ISC_FALSE; } /* make sure the dn exists, or find parent dn in case new object is being added */ ldb_ret = ldb_search(state->samdb, tmp_ctx, &res, dn, LDB_SCOPE_BASE, attrs, "objectClass=dnsNode"); if (ldb_ret == LDB_ERR_NO_SUCH_OBJECT) { ldb_dn_remove_child_components(dn, 1); access_mask = SEC_ADS_CREATE_CHILD; talloc_free(res); } else if (ldb_ret == LDB_SUCCESS) { access_mask = SEC_STD_REQUIRED | SEC_ADS_SELF_WRITE; talloc_free(res); } else { talloc_free(tmp_ctx); return ISC_FALSE; } /* Do ACL check */ ldb_ret = dsdb_check_access_on_dn(state->samdb, tmp_ctx, dn, session_info->security_token, access_mask, NULL); if (ldb_ret != LDB_SUCCESS) { state->log(ISC_LOG_INFO, "samba_dlz: disallowing update of signer=%s name=%s type=%s error=%s", signer, name, type, ldb_strerror(ldb_ret)); talloc_free(tmp_ctx); return ISC_FALSE; } /* Cache session_info, so it can be used in the actual add/delete operation */ state->update_name = talloc_strdup(state, name); if (state->update_name == NULL) { state->log(ISC_LOG_ERROR, "samba_dlz: memory allocation error"); talloc_free(tmp_ctx); return ISC_FALSE; } state->session_info = talloc_steal(state, session_info); state->log(ISC_LOG_INFO, "samba_dlz: allowing update of signer=%s name=%s tcpaddr=%s type=%s key=%s", signer, name, tcpaddr, type, key); talloc_free(tmp_ctx); return ISC_TRUE; }