/* startup the web server task */ static void websrv_task_init(struct task_server *task) { NTSTATUS status; uint16_t port = lp_web_port(task->lp_ctx); const struct model_ops *model_ops; struct web_server_data *wdata; task_server_set_title(task, "task[websrv]"); /* run the web server as a single process */ model_ops = process_model_startup(task->event_ctx, "single"); if (!model_ops) goto failed; if (lp_interfaces(task->lp_ctx) && lp_bind_interfaces_only(task->lp_ctx)) { int num_interfaces; int i; struct interface *ifaces; load_interfaces(NULL, lp_interfaces(task->lp_ctx), &ifaces); num_interfaces = iface_count(ifaces); for(i = 0; i < num_interfaces; i++) { const char *address = iface_n_ip(ifaces, i); status = stream_setup_socket(task->event_ctx, task->lp_ctx, model_ops, &web_stream_ops, "ipv4", address, &port, lp_socket_options(task->lp_ctx), task); if (!NT_STATUS_IS_OK(status)) goto failed; } talloc_free(ifaces); } else { status = stream_setup_socket(task->event_ctx, task->lp_ctx, model_ops, &web_stream_ops, "ipv4", lp_socket_address(task->lp_ctx), &port, lp_socket_options(task->lp_ctx), task); if (!NT_STATUS_IS_OK(status)) goto failed; } /* startup the esp processor - unfortunately we can't do this per connection as that wouldn't allow for session variables */ wdata = talloc_zero(task, struct web_server_data); if (wdata == NULL)goto failed; task->private_data = wdata; wdata->tls_params = tls_initialise(wdata, task->lp_ctx); if (wdata->tls_params == NULL) goto failed; if (!wsgi_initialize(wdata)) goto failed; return; failed: task_server_terminate(task, "websrv_task_init: failed to startup web server task", true); }
bool reload_services(struct smbd_server_connection *sconn, bool (*snumused) (struct smbd_server_connection *, int), bool test) { struct smbXsrv_connection *xconn = NULL; bool ret; if (sconn != NULL) { xconn = sconn->conn; } if (lp_loaded()) { char *fname = lp_next_configfile(talloc_tos()); if (file_exist(fname) && !strcsequal(fname, get_dyn_CONFIGFILE())) { set_dyn_CONFIGFILE(fname); test = False; } TALLOC_FREE(fname); } reopen_logs(); if (test && !lp_file_list_changed()) return(True); lp_killunused(sconn, snumused); ret = lp_load(get_dyn_CONFIGFILE(), false, /* global only */ false, /* save defaults */ true, /* add_ipc */ true); /* initialize globals */ /* perhaps the config filename is now set */ if (!test) { reload_services(sconn, snumused, true); } reopen_logs(); load_interfaces(); if (xconn != NULL) { set_socket_options(xconn->transport.sock, "SO_KEEPALIVE"); set_socket_options(xconn->transport.sock, lp_socket_options()); } mangle_reset_cache(); reset_stat_cache(); /* this forces service parameters to be flushed */ set_current_service(NULL,0,True); return(ret); }
/** * The challenge from the target server, when operating in security=server **/ static NTSTATUS server_get_challenge(struct auth_method_context *ctx, TALLOC_CTX *mem_ctx, uint8_t chal[8]) { struct smb_composite_connect io; struct smbcli_options smb_options; const char **host_list; NTSTATUS status; /* Make a connection to the target server, found by 'password server' in smb.conf */ lp_smbcli_options(ctx->auth_ctx->lp_ctx, &smb_options); /* Make a negprot, WITHOUT SPNEGO, so we get a challenge nice an easy */ io.in.options.use_spnego = false; /* Hope we don't get * (the default), as this won't work... */ host_list = lp_passwordserver(ctx->auth_ctx->lp_ctx); if (!host_list) { return NT_STATUS_INTERNAL_ERROR; } io.in.dest_host = host_list[0]; if (strequal(io.in.dest_host, "*")) { return NT_STATUS_INTERNAL_ERROR; } io.in.dest_ports = lp_smb_ports(ctx->auth_ctx->lp_ctx); io.in.socket_options = lp_socket_options(ctx->auth_ctx->lp_ctx); io.in.gensec_settings = lp_gensec_settings(mem_ctx, ctx->auth_ctx->lp_ctx); io.in.called_name = strupper_talloc(mem_ctx, io.in.dest_host); /* We don't want to get as far as the session setup */ io.in.credentials = cli_credentials_init_anon(mem_ctx); cli_credentials_set_workstation(io.in.credentials, lp_netbios_name(ctx->auth_ctx->lp_ctx), CRED_SPECIFIED); io.in.service = NULL; io.in.workgroup = ""; /* only used with SPNEGO, disabled above */ io.in.options = smb_options; io.in.iconv_convenience = lp_iconv_convenience(ctx->auth_ctx->lp_ctx); lp_smbcli_session_options(ctx->auth_ctx->lp_ctx, &io.in.session_options); status = smb_composite_connect(&io, mem_ctx, lp_resolve_context(ctx->auth_ctx->lp_ctx), ctx->auth_ctx->event_ctx); NT_STATUS_NOT_OK_RETURN(status); if (io.out.tree->session->transport->negotiate.secblob.length != 8) { return NT_STATUS_INTERNAL_ERROR; } memcpy(chal, io.out.tree->session->transport->negotiate.secblob.data, 8); ctx->private_data = talloc_steal(ctx, io.out.tree->session); return NT_STATUS_OK; }
NTSTATUS svc_UploadService(const char *hostname, struct cli_credentials * credentials, int flags) { struct smb_composite_savefile *io; struct smbcli_state *cli; NTSTATUS status; struct smbcli_options options; struct smbcli_session_options session_options; lp_smbcli_options(cmdline_lp_ctx, &options); lp_smbcli_session_options(cmdline_lp_ctx, &session_options); status = smbcli_full_connection(NULL, &cli, hostname, lp_smb_ports(cmdline_lp_ctx), "ADMIN$", NULL, lp_socket_options(cmdline_lp_ctx), credentials, lp_resolve_context(cmdline_lp_ctx), ev_ctx, &options, &session_options, lp_iconv_convenience(cmdline_lp_ctx), lp_gensec_settings(NULL, cmdline_lp_ctx)); NT_ERR(status, 1, "Failed to open ADMIN$ share"); if (flags & SVC_FORCE_UPLOAD) { smbcli_unlink(cli->tree, "winexesvc.exe"); } else { int fd = smbcli_open(cli->tree, "winexesvc.exe", O_RDONLY, DENY_NONE); if (fd >= 0) { smbcli_close(cli->tree, fd); return status; } } io = talloc_zero(cli->tree, struct smb_composite_savefile); io->in.fname = "winexesvc.exe"; if (flags & SVC_OSCHOOSE) { status = smbcli_chkpath(cli->tree, "SysWoW64"); } if ((flags & SVC_OSCHOOSE && NT_STATUS_IS_OK(status)) || (flags & SVC_OS64BIT)) { DEBUG(1, ("svc_UploadService: Installing 64bit winexesvc.exe\n")); io->in.data = winexesvc64_exe; io->in.size = winexesvc64_exe_len; } else { DEBUG(1, ("svc_UploadService: Installing 32bit winexesvc.exe\n")); io->in.data = winexesvc32_exe; io->in.size = winexesvc32_exe_len; } status = smb_composite_savefile(cli->tree, io); NT_ERR(status, 1, "Failed to save ADMIN$/%s", io->in.fname); talloc_free(io); smbcli_tdis(cli); return status; }
bool reload_services(struct messaging_context *msg_ctx, int smb_sock, bool test) { bool ret; if (lp_loaded()) { char *fname = lp_configfile(); if (file_exist(fname) && !strcsequal(fname, get_dyn_CONFIGFILE())) { set_dyn_CONFIGFILE(fname); test = False; } TALLOC_FREE(fname); } reopen_logs(); if (test && !lp_file_list_changed()) return(True); lp_killunused(conn_snum_used); ret = lp_load(get_dyn_CONFIGFILE(), False, False, True, True); /* perhaps the config filename is now set */ if (!test) reload_services(msg_ctx, smb_sock, True); reopen_logs(); load_interfaces(); if (smb_sock != -1) { set_socket_options(smb_sock,"SO_KEEPALIVE"); set_socket_options(smb_sock, lp_socket_options()); } mangle_reset_cache(); reset_stat_cache(); /* this forces service parameters to be flushed */ set_current_service(NULL,0,True); return(ret); }
static bool smbd_open_one_socket(struct smbd_parent_context *parent, struct tevent_context *ev_ctx, struct messaging_context *msg_ctx, const struct sockaddr_storage *ifss, uint16_t port) { struct smbd_open_socket *s; s = talloc(parent, struct smbd_open_socket); if (!s) { return false; } s->parent = parent; s->fd = open_socket_in(SOCK_STREAM, port, parent->sockets == NULL ? 0 : 2, ifss, true); if (s->fd == -1) { DEBUG(0,("smbd_open_once_socket: open_socket_in: " "%s\n", strerror(errno))); TALLOC_FREE(s); /* * We ignore an error here, as we've done before */ return true; } /* ready to listen */ set_socket_options(s->fd, "SO_KEEPALIVE"); set_socket_options(s->fd, lp_socket_options()); /* Set server socket to * non-blocking for the accept. */ set_blocking(s->fd, False); if (listen(s->fd, SMBD_LISTEN_BACKLOG) == -1) { DEBUG(0,("open_sockets_smbd: listen: " "%s\n", strerror(errno))); close(s->fd); TALLOC_FREE(s); return false; } s->msg_ctx = msg_ctx; s->fde = tevent_add_fd(ev_ctx, s, s->fd, TEVENT_FD_READ, smbd_accept_connection, s); if (!s->fde) { DEBUG(0,("open_sockets_smbd: " "tevent_add_fd: %s\n", strerror(errno))); close(s->fd); TALLOC_FREE(s); return false; } tevent_fd_set_close_fn(s->fde, smbd_open_socket_close_fn); DLIST_ADD_END(parent->sockets, s, struct smbd_open_socket *); return true; }
/***************************************************** return a connection to a server *******************************************************/ static struct smbcli_state *connect_one(struct tevent_context *ev, struct loadparm_context *lp_ctx, TALLOC_CTX *mem_ctx, char *share, int snum, int conn) { struct smbcli_state *c; char *server, *myname; NTSTATUS status; int retries = 10; struct smbcli_options options; struct smbcli_session_options session_options; lp_smbcli_options(lp_ctx, &options); lp_smbcli_session_options(lp_ctx, &session_options); printf("connect_one(%s, %d, %d)\n", share, snum, conn); server = talloc_strdup(mem_ctx, share+2); share = strchr_m(server,'\\'); if (!share) return NULL; *share = 0; share++; if (snum == 0) { char **unc_list = NULL; int num_unc_names; const char *p; p = lp_parm_string(lp_ctx, NULL, "torture", "unclist"); if (p) { char *h, *s; unc_list = file_lines_load(p, &num_unc_names, 0, NULL); if (!unc_list || num_unc_names <= 0) { printf("Failed to load unc names list from '%s'\n", p); exit(1); } if (!smbcli_parse_unc(unc_list[conn % num_unc_names], NULL, &h, &s)) { printf("Failed to parse UNC name %s\n", unc_list[conn % num_unc_names]); exit(1); } server = talloc_strdup(mem_ctx, h); share = talloc_strdup(mem_ctx, s); } } myname = talloc_asprintf(mem_ctx, "lock-%u-%u", getpid(), snum); cli_credentials_set_workstation(servers[snum], myname, CRED_SPECIFIED); do { printf("\\\\%s\\%s\n", server, share); status = smbcli_full_connection(NULL, &c, server, lp_smb_ports(lp_ctx), share, NULL, lp_socket_options(lp_ctx), servers[snum], lp_resolve_context(lp_ctx), ev, &options, &session_options, lp_iconv_convenience(lp_ctx), lp_gensec_settings(mem_ctx, lp_ctx)); if (!NT_STATUS_IS_OK(status)) { sleep(2); } } while (!NT_STATUS_IS_OK(status) && retries--); if (!NT_STATUS_IS_OK(status)) { return NULL; } return c; }
static int copy_files(struct tevent_context *ev, struct loadparm_context *lp_ctx) { uint8_t * iobuf; /* IO buffer. */ uint64_t iomax; /* Size of the IO buffer. */ uint64_t data_size; /* Amount of data in the IO buffer. */ uint64_t ibs; uint64_t obs; uint64_t count; struct dd_iohandle * ifile; struct dd_iohandle * ofile; struct smbcli_options options; struct smbcli_session_options session_options; ibs = check_arg_numeric("ibs"); obs = check_arg_numeric("obs"); count = check_arg_numeric("count"); lp_smbcli_options(lp_ctx, &options); lp_smbcli_session_options(lp_ctx, &session_options); /* Allocate IO buffer. We need more than the max IO size because we * could accumulate a remainder if ibs and obs don't match. */ iomax = 2 * MAX(ibs, obs); if ((iobuf = malloc_array_p(uint8_t, iomax)) == NULL) { fprintf(stderr, "%s: failed to allocate IO buffer of %llu bytes\n", PROGNAME, (unsigned long long)iomax); return(EOM_EXIT_CODE); } options.max_xmit = MAX(ibs, obs); DEBUG(4, ("IO buffer size is %llu, max xmit is %d\n", (unsigned long long)iomax, options.max_xmit)); if (!(ifile = open_file(lp_resolve_context(lp_ctx), ev, "if", lp_smb_ports(lp_ctx), &options, lp_socket_options(lp_ctx), &session_options, lp_iconv_convenience(lp_ctx), lp_gensec_settings(lp_ctx, lp_ctx)))) { return(FILESYS_EXIT_CODE); } if (!(ofile = open_file(lp_resolve_context(lp_ctx), ev, "of", lp_smb_ports(lp_ctx), &options, lp_socket_options(lp_ctx), &session_options, lp_iconv_convenience(lp_ctx), lp_gensec_settings(lp_ctx, lp_ctx)))) { return(FILESYS_EXIT_CODE); } /* Seek the files to their respective starting points. */ ifile->io_seek(ifile, check_arg_numeric("skip") * ibs); ofile->io_seek(ofile, check_arg_numeric("seek") * obs); DEBUG(4, ("max xmit was negotiated to be %d\n", options.max_xmit)); for (data_size = 0;;) { /* Handle signals. We are somewhat compatible with GNU dd. * SIGINT makes us stop, but still print transfer statistics. * SIGUSR1 makes us print transfer statistics but we continue * copying. */ if (dd_sigint) { break; } if (dd_sigusr1) { print_transfer_stats(); dd_sigusr1 = 0; } if (ifile->io_flags & DD_END_OF_FILE) { DEBUG(4, ("flushing %llu bytes at EOF\n", (unsigned long long)data_size)); while (data_size > 0) { if (!dd_flush_block(ofile, iobuf, &data_size, obs)) { return(IOERROR_EXIT_CODE); } } goto done; } /* Try and read enough blocks of ibs bytes to be able write * out one of obs bytes. */ if (!dd_fill_block(ifile, iobuf, &data_size, obs, ibs)) { return(IOERROR_EXIT_CODE); } if (data_size == 0) { /* Done. */ SMB_ASSERT(ifile->io_flags & DD_END_OF_FILE); } /* Stop reading when we hit the block count. */ if (dd_stats.in.bytes >= (ibs * count)) { ifile->io_flags |= DD_END_OF_FILE; } /* If we wanted to be a legitimate dd, we would do character * conversions and other shenanigans here. */ /* Flush what we read in units of obs bytes. We want to have * at least obs bytes in the IO buffer but might not if the * file is too small. */ if (data_size && !dd_flush_block(ofile, iobuf, &data_size, obs)) { return(IOERROR_EXIT_CODE); } } done: print_transfer_stats(); return(0); }
static int fork_tcon_client(struct torture_context *tctx, int *tcon_count, unsigned tcon_timelimit, const char *host, const char *share) { pid_t child; struct smbcli_state *cli; struct timeval end; struct timeval now; struct smbcli_options options; struct smbcli_session_options session_options; lp_smbcli_options(tctx->lp_ctx, &options); lp_smbcli_session_options(tctx->lp_ctx, &session_options); child = fork(); if (child == -1) { printf("failed to fork child: %s\n,", strerror(errno)); return -1; } else if (child != 0) { /* Parent, just return. */ return 0; } /* Child. Just make as many connections as possible within the * time limit. Don't bother synchronising the child start times * because it's probably not work the effort, and a bit of startup * jitter is probably a more realistic test. */ end = timeval_current(); now = timeval_current(); end.tv_sec += tcon_timelimit; *tcon_count = 0; while (timeval_compare(&now, &end) == -1) { NTSTATUS status; status = smbcli_full_connection(NULL, &cli, host, lp_smb_ports(tctx->lp_ctx), share, NULL, lp_socket_options(tctx->lp_ctx), cmdline_credentials, lp_resolve_context(tctx->lp_ctx), tctx->ev, &options, &session_options, lp_iconv_convenience(tctx->lp_ctx), lp_gensec_settings(tctx, tctx->lp_ctx)); if (!NT_STATUS_IS_OK(status)) { printf("failed to connect to //%s/%s: %s\n", host, share, nt_errstr(status)); goto done; } smbcli_tdis(cli); talloc_free(cli); *tcon_count = *tcon_count + 1; now = timeval_current(); } done: exit(0); }
static int do_global_checks(void) { int ret = 0; SMB_STRUCT_STAT st; const char *socket_options; if (lp_security() >= SEC_DOMAIN && !lp_encrypt_passwords()) { fprintf(stderr, "ERROR: in 'security=domain' mode the " "'encrypt passwords' parameter must always be " "set to 'true'.\n\n"); ret = 1; } if (lp_we_are_a_wins_server() && lp_wins_server_list()) { fprintf(stderr, "ERROR: both 'wins support = true' and " "'wins server = <server list>' cannot be set in " "the smb.conf file. nmbd will abort with this " "setting.\n\n"); ret = 1; } if (strequal(lp_workgroup(), lp_netbios_name())) { fprintf(stderr, "WARNING: 'workgroup' and 'netbios name' " "must differ.\n\n"); } if (!directory_exist_stat(lp_lock_directory(), &st)) { fprintf(stderr, "ERROR: lock directory %s does not exist\n\n", lp_lock_directory()); ret = 1; } else if ((st.st_ex_mode & 0777) != 0755) { fprintf(stderr, "WARNING: lock directory %s should have " "permissions 0755 for browsing to work\n\n", lp_lock_directory()); } if (!directory_exist_stat(lp_state_directory(), &st)) { fprintf(stderr, "ERROR: state directory %s does not exist\n\n", lp_state_directory()); ret = 1; } else if ((st.st_ex_mode & 0777) != 0755) { fprintf(stderr, "WARNING: state directory %s should have " "permissions 0755 for browsing to work\n\n", lp_state_directory()); } if (!directory_exist_stat(lp_cache_directory(), &st)) { fprintf(stderr, "ERROR: cache directory %s does not exist\n\n", lp_cache_directory()); ret = 1; } else if ((st.st_ex_mode & 0777) != 0755) { fprintf(stderr, "WARNING: cache directory %s should have " "permissions 0755 for browsing to work\n\n", lp_cache_directory()); } if (!directory_exist_stat(lp_pid_directory(), &st)) { fprintf(stderr, "ERROR: pid directory %s does not exist\n\n", lp_pid_directory()); ret = 1; } if (lp_passdb_expand_explicit()) { fprintf(stderr, "WARNING: passdb expand explicit = yes is " "deprecated\n\n"); } /* * Socket options. */ socket_options = lp_socket_options(); if (socket_options != NULL && (strstr(socket_options, "SO_SNDBUF") || strstr(socket_options, "SO_RCVBUF") || strstr(socket_options, "SO_SNDLOWAT") || strstr(socket_options, "SO_RCVLOWAT"))) { fprintf(stderr, "WARNING: socket options = %s\n" "This warning is printed because you set one of the\n" "following options: SO_SNDBUF, SO_RCVBUF, SO_SNDLOWAT,\n" "SO_RCVLOWAT\n" "Modern server operating systems are tuned for\n" "high network performance in the majority of situations;\n" "when you set 'socket options' you are overriding those\n" "settings.\n" "Linux in particular has an auto-tuning mechanism for\n" "buffer sizes (SO_SNDBUF, SO_RCVBUF) that will be\n" "disabled if you specify a socket buffer size. This can\n" "potentially cripple your TCP/IP stack.\n\n" "Getting the 'socket options' correct can make a big\n" "difference to your performance, but getting them wrong\n" "can degrade it by just as much. As with any other low\n" "level setting, if you must make changes to it, make\n " "small changes and test the effect before making any\n" "large changes.\n\n", socket_options); } /* * Password server sanity checks. */ if((lp_security() >= SEC_DOMAIN) && !*lp_password_server()) { const char *sec_setting; if(lp_security() == SEC_DOMAIN) sec_setting = "domain"; else if(lp_security() == SEC_ADS) sec_setting = "ads"; else sec_setting = ""; fprintf(stderr, "ERROR: The setting 'security=%s' requires the " "'password server' parameter be set to the " "default value * or a valid password server.\n\n", sec_setting ); ret = 1; } if((lp_security() >= SEC_DOMAIN) && (strcmp(lp_password_server(), "*") != 0)) { const char *sec_setting; if(lp_security() == SEC_DOMAIN) sec_setting = "domain"; else if(lp_security() == SEC_ADS) sec_setting = "ads"; else sec_setting = ""; fprintf(stderr, "WARNING: The setting 'security=%s' should NOT " "be combined with the 'password server' " "parameter.\n" "(by default Samba will discover the correct DC " "to contact automatically).\n\n", sec_setting ); } /* * Password chat sanity checks. */ if(lp_security() == SEC_USER && lp_unix_password_sync()) { /* * Check that we have a valid lp_passwd_program() if not using pam. */ #ifdef WITH_PAM if (!lp_pam_password_change()) { #endif if((lp_passwd_program(talloc_tos()) == NULL) || (strlen(lp_passwd_program(talloc_tos())) == 0)) { fprintf(stderr, "ERROR: the 'unix password sync' " "parameter is set and there is no valid " "'passwd program' parameter.\n\n"); ret = 1; } else { const char *passwd_prog; char *truncated_prog = NULL; const char *p; passwd_prog = lp_passwd_program(talloc_tos()); p = passwd_prog; next_token_talloc(talloc_tos(), &p, &truncated_prog, NULL); if (truncated_prog && access(truncated_prog, F_OK) == -1) { fprintf(stderr, "ERROR: the 'unix password sync' " "parameter is set and the " "'passwd program' (%s) cannot be " "executed (error was %s).\n\n", truncated_prog, strerror(errno)); ret = 1; } } #ifdef WITH_PAM } #endif if(lp_passwd_chat(talloc_tos()) == NULL) { fprintf(stderr, "ERROR: the 'unix password sync' parameter is " "set and there is no valid 'passwd chat' " "parameter.\n\n"); ret = 1; } if ((lp_passwd_program(talloc_tos()) != NULL) && (strlen(lp_passwd_program(talloc_tos())) > 0)) { /* check if there's a %u parameter present */ if(strstr_m(lp_passwd_program(talloc_tos()), "%u") == NULL) { fprintf(stderr, "ERROR: the 'passwd program' (%s) " "requires a '%%u' parameter.\n\n", lp_passwd_program(talloc_tos())); ret = 1; } } /* * Check that we have a valid script and that it hasn't * been written to expect the old password. */ if(lp_encrypt_passwords()) { if(strstr_m( lp_passwd_chat(talloc_tos()), "%o")!=NULL) { fprintf(stderr, "ERROR: the 'passwd chat' script [%s] " "expects to use the old plaintext " "password via the %%o substitution. With " "encrypted passwords this is not " "possible.\n\n", lp_passwd_chat(talloc_tos()) ); ret = 1; } } } if (strlen(lp_winbind_separator()) != 1) { fprintf(stderr, "ERROR: the 'winbind separator' parameter must " "be a single character.\n\n"); ret = 1; } if (*lp_winbind_separator() == '+') { fprintf(stderr, "'winbind separator = +' might cause problems " "with group membership.\n\n"); } if (lp_algorithmic_rid_base() < BASE_RID) { /* Try to prevent admin foot-shooting, we can't put algorithmic rids below 1000, that's the 'well known RIDs' on NT */ fprintf(stderr, "'algorithmic rid base' must be equal to or " "above %lu\n\n", BASE_RID); } if (lp_algorithmic_rid_base() & 1) { fprintf(stderr, "'algorithmic rid base' must be even.\n\n"); } #ifndef HAVE_DLOPEN if (lp_preload_modules()) { fprintf(stderr, "WARNING: 'preload modules = ' set while loading " "plugins not supported.\n\n"); } #endif if (!lp_passdb_backend()) { fprintf(stderr, "ERROR: passdb backend must have a value or be " "left out\n\n"); } if (lp_os_level() > 255) { fprintf(stderr, "WARNING: Maximum value for 'os level' is " "255!\n\n"); } if (strequal(lp_dos_charset(), "UTF8") || strequal(lp_dos_charset(), "UTF-8")) { fprintf(stderr, "ERROR: 'dos charset' must not be UTF8\n\n"); ret = 1; } return ret; }
/* this is called when a socket connection is established to a client and we want to start talking. The setup of the system is done from here */ static int start_daemon(int fd) { char line[200]; char *motd; int i = -1; extern char *config_file; extern int remote_version; if (!lp_load(config_file, 0)) { exit_cleanup(RERR_SYNTAX); } set_socket_options(fd,"SO_KEEPALIVE"); set_socket_options(fd,lp_socket_options()); io_printf(fd,"@RSYNCD: %d\n", PROTOCOL_VERSION); motd = lp_motd_file(); if (motd && *motd) { FILE *f = fopen(motd,"r"); while (f && !feof(f)) { int len = fread(line, 1, sizeof(line)-1, f); if (len > 0) { line[len] = 0; io_printf(fd,"%s", line); } } if (f) fclose(f); io_printf(fd,"\n"); } if (!read_line(fd, line, sizeof(line)-1)) { return -1; } if (sscanf(line,"@RSYNCD: %d", &remote_version) != 1) { io_printf(fd,"@ERROR: protocol startup error\n"); return -1; } while (i == -1) { line[0] = 0; if (!read_line(fd, line, sizeof(line)-1)) { return -1; } if (!*line || strcmp(line,"#list")==0) { send_listing(fd); return -1; } if (*line == '#') { /* it's some sort of command that I don't understand */ io_printf(fd,"@ERROR: Unknown command '%s'\n", line); return -1; } i = lp_number(line); if (i == -1) { io_printf(fd,"@ERROR: Unknown module '%s'\n", line); return -1; } } return rsync_module(fd, i); }
/* open the ldap server sockets */ static void ldapsrv_task_init(struct task_server *task) { char *ldapi_path; #ifdef WITH_LDAPI_PRIV_SOCKET char *priv_dir; #endif struct ldapsrv_service *ldap_service; NTSTATUS status; const struct model_ops *model_ops; switch (lp_server_role(task->lp_ctx)) { case ROLE_STANDALONE: task_server_terminate(task, "ldap_server: no LDAP server required in standalone configuration", false); return; case ROLE_DOMAIN_MEMBER: task_server_terminate(task, "ldap_server: no LDAP server required in member server configuration", false); return; case ROLE_DOMAIN_CONTROLLER: /* Yes, we want an LDAP server */ break; } task_server_set_title(task, "task[ldapsrv]"); /* run the ldap server as a single process */ model_ops = process_model_startup(task->event_ctx, "single"); if (!model_ops) goto failed; ldap_service = talloc_zero(task, struct ldapsrv_service); if (ldap_service == NULL) goto failed; ldap_service->task = task; ldap_service->tls_params = tls_initialise(ldap_service, task->lp_ctx); if (ldap_service->tls_params == NULL) goto failed; if (lp_interfaces(task->lp_ctx) && lp_bind_interfaces_only(task->lp_ctx)) { struct interface *ifaces; int num_interfaces; int i; load_interfaces(task, lp_interfaces(task->lp_ctx), &ifaces); num_interfaces = iface_count(ifaces); /* We have been given an interfaces line, and been told to only bind to those interfaces. Create a socket per interface and bind to only these. */ for(i = 0; i < num_interfaces; i++) { const char *address = iface_n_ip(ifaces, i); status = add_socket(task->event_ctx, task->lp_ctx, model_ops, address, ldap_service); if (!NT_STATUS_IS_OK(status)) goto failed; } } else { status = add_socket(task->event_ctx, task->lp_ctx, model_ops, lp_socket_address(task->lp_ctx), ldap_service); if (!NT_STATUS_IS_OK(status)) goto failed; } ldapi_path = private_path(ldap_service, task->lp_ctx, "ldapi"); if (!ldapi_path) { goto failed; } status = stream_setup_socket(task->event_ctx, task->lp_ctx, model_ops, &ldap_stream_nonpriv_ops, "unix", ldapi_path, NULL, lp_socket_options(task->lp_ctx), ldap_service); talloc_free(ldapi_path); if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("ldapsrv failed to bind to %s - %s\n", ldapi_path, nt_errstr(status))); } #ifdef WITH_LDAPI_PRIV_SOCKET priv_dir = private_path(ldap_service, task->lp_ctx, "ldap_priv"); if (priv_dir == NULL) { goto failed; } /* * Make sure the directory for the privileged ldapi socket exists, and * is of the correct permissions */ if (!directory_create_or_exist(priv_dir, geteuid(), 0750)) { task_server_terminate(task, "Cannot create ldap " "privileged ldapi directory", true); return; } ldapi_path = talloc_asprintf(ldap_service, "%s/ldapi", priv_dir); talloc_free(priv_dir); if (ldapi_path == NULL) { goto failed; } status = stream_setup_socket(task->event_ctx, task->lp_ctx, model_ops, &ldap_stream_priv_ops, "unix", ldapi_path, NULL, lp_socket_options(task->lp_ctx), ldap_service); talloc_free(ldapi_path); if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("ldapsrv failed to bind to %s - %s\n", ldapi_path, nt_errstr(status))); } #endif return; failed: task_server_terminate(task, "Failed to startup ldap server task", true); }
/* add a socket address to the list of events, one event per port */ static NTSTATUS add_socket(struct tevent_context *event_context, struct loadparm_context *lp_ctx, const struct model_ops *model_ops, const char *address, struct ldapsrv_service *ldap_service) { uint16_t port = 389; NTSTATUS status; struct ldb_context *ldb; status = stream_setup_socket(event_context, lp_ctx, model_ops, &ldap_stream_nonpriv_ops, "ipv4", address, &port, lp_socket_options(lp_ctx), ldap_service); if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("ldapsrv failed to bind to %s:%u - %s\n", address, port, nt_errstr(status))); } if (tls_support(ldap_service->tls_params)) { /* add ldaps server */ port = 636; status = stream_setup_socket(event_context, lp_ctx, model_ops, &ldap_stream_nonpriv_ops, "ipv4", address, &port, lp_socket_options(lp_ctx), ldap_service); if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("ldapsrv failed to bind to %s:%u - %s\n", address, port, nt_errstr(status))); } } /* Load LDAP database, but only to read our settings */ ldb = samdb_connect(ldap_service, ldap_service->task->event_ctx, lp_ctx, system_session(ldap_service, lp_ctx)); if (!ldb) { return NT_STATUS_INTERNAL_DB_CORRUPTION; } if (samdb_is_gc(ldb)) { port = 3268; status = stream_setup_socket(event_context, lp_ctx, model_ops, &ldap_stream_nonpriv_ops, "ipv4", address, &port, lp_socket_options(lp_ctx), ldap_service); if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("ldapsrv failed to bind to %s:%u - %s\n", address, port, nt_errstr(status))); } } /* And once we are bound, free the tempoary ldb, it will * connect again on each incoming LDAP connection */ talloc_free(ldb); return status; }
NTSTATUS svc_uninstall(const char *hostname, struct cli_credentials * credentials) { NTSTATUS status; struct dcerpc_pipe *svc_pipe; struct policy_handle scm_handle; struct policy_handle svc_handle; struct SERVICE_STATUS svc_status; struct smbcli_options options; struct smbcli_session_options session_options; lp_smbcli_options(cmdline_lp_ctx, &options); lp_smbcli_session_options(cmdline_lp_ctx, &session_options); status = svc_pipe_connect(&svc_pipe, hostname, credentials); NT_ERR(status, 1, "Cannot connect to svcctl pipe"); status = svc_OpenSCManager(svc_pipe, hostname, &scm_handle); NT_ERR(status, 1, "OpenSCManager failed"); status = svc_OpenService(svc_pipe, &scm_handle, "winexesvc", &svc_handle); NT_ERR(status, 1, "OpenService failed"); DEBUG(1, ("OpenService - %s\n", nt_errstr(status))); if (NT_STATUS_IS_OK(status)) { status = svc_ControlService(svc_pipe, &svc_handle, SERVICE_CONTROL_STOP, &svc_status); { struct SERVICE_STATUS s; do { msleep(100); status = svc_QueryServiceStatus(svc_pipe, &svc_handle, &s); NT_ERR(status, 1, "QueryServiceStatus failed"); } while (s.state == SVCCTL_STOP_PENDING); if (s.state != SVCCTL_STOPPED) { DEBUG(0, ("Service cannot stop, status=0x%08X\n", s.state)); return NT_STATUS_UNSUCCESSFUL; } } DEBUG(1, ("StopService - %s\n", nt_errstr(status))); status = svc_DeleteService(svc_pipe, &svc_handle); DEBUG(1, ("DeleteService - %s\n", nt_errstr(status))); status = svc_CloseServiceHandle(svc_pipe, &svc_handle); DEBUG(1, ("CloseServiceHandle - %s\n", nt_errstr(status))); } svc_CloseServiceHandle(svc_pipe, &scm_handle); DEBUG(1, ("CloseSCMHandle - %s\n", nt_errstr(status))); struct smbcli_state *cli; status = smbcli_full_connection(NULL, &cli, hostname, lp_smb_ports(cmdline_lp_ctx), "ADMIN$", NULL, lp_socket_options(cmdline_lp_ctx), credentials, lp_resolve_context(cmdline_lp_ctx), ev_ctx, &options, &session_options, lp_iconv_convenience(cmdline_lp_ctx), lp_gensec_settings(NULL, cmdline_lp_ctx)); NT_ERR(status, 1, "Failed to open ADMIN$ share"); /* Give winexesvc some time to exit */ msleep(300); status = smbcli_unlink(cli->tree, "winexesvc.exe"); DEBUG(1, ("Delete winexesvc.exe - %s\n", nt_errstr(status))); status = smbcli_tdis(cli); DEBUG(1, ("Closing ADMIN$ - %s\n", nt_errstr(status))); return status; }
/* 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; }
/* test a query FS info by asking for share's GUID */ static bool test_fsinfo(struct smbcli_state *cli, struct torture_context *tctx) { char *guid = NULL; NTSTATUS status; struct smb_composite_fsinfo io1; struct composite_context **c; int i; extern int torture_numops; struct tevent_context *event_ctx; int *count = talloc_zero(tctx, int); bool ret = true; io1.in.dest_host = torture_setting_string(tctx, "host", NULL); io1.in.dest_ports = lp_smb_ports(tctx->lp_ctx); io1.in.socket_options = lp_socket_options(tctx->lp_ctx); io1.in.called_name = torture_setting_string(tctx, "host", NULL); io1.in.service = torture_setting_string(tctx, "share", NULL); io1.in.service_type = "A:"; io1.in.credentials = cmdline_credentials; io1.in.workgroup = lp_workgroup(tctx->lp_ctx); io1.in.level = RAW_QFS_OBJECTID_INFORMATION; io1.in.iconv_convenience = lp_iconv_convenience(tctx->lp_ctx); io1.in.gensec_settings = lp_gensec_settings(tctx, tctx->lp_ctx); printf("testing parallel queryfsinfo [Object ID] with %d ops\n", torture_numops); event_ctx = tctx->ev; c = talloc_array(tctx, struct composite_context *, torture_numops); for (i=0; i<torture_numops; i++) { c[i] = smb_composite_fsinfo_send(cli->tree, &io1, lp_resolve_context(tctx->lp_ctx)); c[i]->async.fn = loadfile_complete; c[i]->async.private_data = count; } printf("waiting for completion\n"); while (*count < torture_numops) { event_loop_once(event_ctx); if (torture_setting_bool(tctx, "progress", true)) { printf("(%s) count=%d\r", __location__, *count); fflush(stdout); } } printf("count=%d\n", *count); for (i=0;i<torture_numops;i++) { status = smb_composite_fsinfo_recv(c[i], tctx); if (!NT_STATUS_IS_OK(status)) { printf("(%s) fsinfo[%d] failed - %s\n", __location__, i, nt_errstr(status)); ret = false; continue; } if (io1.out.fsinfo->generic.level != RAW_QFS_OBJECTID_INFORMATION) { printf("(%s) wrong level in returned info - %d " "should be %d\n", __location__, io1.out.fsinfo->generic.level, RAW_QFS_OBJECTID_INFORMATION); ret = false; continue; } guid=GUID_string(tctx, &io1.out.fsinfo->objectid_information.out.guid); printf("[%d] GUID: %s\n", i, guid); } return ret; }