/* 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; }
/* 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; }