void reload_printers(void) { int snum; int n_services = lp_numservices(); int pnum = lp_servicenumber(PRINTERS_NAME); const char *pname; pcap_cache_reload(); /* remove stale printers */ for (snum = 0; snum < n_services; snum++) { /* avoid removing PRINTERS_NAME or non-autoloaded printers */ if (snum == pnum || !(lp_snum_ok(snum) && lp_print_ok(snum) && lp_autoloaded(snum))) continue; pname = lp_printername(snum); if (!pcap_printername_ok(pname)) { DEBUG(3, ("removing stale printer %s\n", pname)); if (is_printer_published(NULL, snum, NULL)) nt_printer_publish(NULL, snum, SPOOL_DS_UNPUBLISH); del_a_printer(pname); lp_killservice(snum); } } load_printers(); }
uint16 DosNetShareEnum(PCONN_HND phnd, uint16 sLevel, RCVBUF pbBuffer, RCVBUFLEN cbBuffer, ENTCOUNT * pcEntriesRead, uint16 *pcTotalAvail) { int i; *pcEntriesRead = 0; *pcTotalAvail = 0; DEBUG(10,("DosNetShareEnum: %d buf %d\n", sLevel, cbBuffer)); for (i = 0; i < lp_numservices(); i++) { DEBUG(10,("service %d [%s]\n", i, lp_servicename(i))); if (!lp_browseable(i) || !lp_snum_ok(i)) continue; (*pcTotalAvail)++; } for (i = 0; i < lp_numservices(); i++) { if (!lp_browseable(i) || !lp_snum_ok(i)) continue; switch (sLevel) { case 1: { SHARE_INFO_1 *sh1 = (SHARE_INFO_1*)pbBuffer; SHARE_INFO_1 *sh1_i; if (cbBuffer < sizeof(SHARE_INFO_1) * ((*pcEntriesRead)+1)) return ERRmoredata; sh1_i = &sh1[(*pcEntriesRead)]; fill_share_1(sh1_i, i); break; } default: { return ERRunknownlevel; } } (*pcEntriesRead)++; } return ERRsuccess; }
/* send a list of available modules to the client. Don't list those with "list = False". */ static void send_listing(int fd) { int n = lp_numservices(); int i; for (i=0;i<n;i++) if (lp_list(i)) io_printf(fd, "%-15s\t%s\n", lp_name(i), lp_comment(i)); }
/**************************************************************************** purge stale printers and reload from pre-populated pcap cache **************************************************************************/ void reload_printers(struct tevent_context *ev, struct messaging_context *msg_ctx) { int n_services; int pnum; int snum; const char *pname; n_services = lp_numservices(); pnum = lp_servicenumber(PRINTERS_NAME); DEBUG(10, ("reloading printer services from pcap cache\n")); /* * Add default config for printers added to smb.conf file and remove * stale printers */ for (snum = 0; snum < n_services; snum++) { /* avoid removing PRINTERS_NAME */ if (snum == pnum) { continue; } /* skip no-printer services */ if (!(lp_snum_ok(snum) && lp_print_ok(snum))) { continue; } pname = lp_printername(snum); /* check printer, but avoid removing non-autoloaded printers */ if (lp_autoloaded(snum) && !pcap_printername_ok(pname)) { DEBUG(3, ("removing stale printer %s\n", pname)); lp_killservice(snum); } } /* Make sure deleted printers are gone */ load_printers(ev, msg_ctx); }
int onefs_load_config(connection_struct *conn) { int snum = SNUM(conn); int share_count = lp_numservices(); /* Share config */ if (!pvfs_share_config) { if (share_count <= ONEFS_DATA_FASTBUF) pvfs_share_config = vfs_share_config; else { pvfs_share_config = SMB_MALLOC_ARRAY(struct onefs_vfs_share_config, share_count); if (!pvfs_share_config) { errno = ENOMEM; return -1; } memset(pvfs_share_config, 0, (sizeof(struct onefs_vfs_share_config) * share_count)); } } if ((pvfs_share_config[snum].init_flags & ONEFS_VFS_CONFIG_INITIALIZED) == 0) { pvfs_share_config[snum].init_flags = ONEFS_VFS_CONFIG_INITIALIZED; onefs_load_faketimestamp_config(conn, &pvfs_share_config[snum]); } /* Global config */ onefs_load_global_config(conn); return 0; }
/* loop over all services, displaying them one after the other */ static void show_services(void) { int i; int n; int allparameters = cgi_boolean("allparameters", 0); printf("<FORM METHOD=POST>\n"); printf("<p>Show all parameters?\n"); printf("<INPUT NAME=allparameters TYPE=checkbox VALUE=1 %s>\n", allparameters?"CHECKED":""); printf("<INPUT TYPE=submit NAME=reload VALUE=Reload>\n"); printf("</FORM>\n"); n = lp_numservices(); show_service(GLOBALS_SNUM, allparameters); show_service(DEFAULTS_SNUM, allparameters); for (i=0;i<n;i++) if (VALID_SNUM(i)) show_service(i, allparameters); }
/** * @brief Purge stale printer shares and reload from pre-populated pcap cache. * * This function should normally only be called as a callback on a successful * pcap_cache_reload(), or on client enumeration. * * @param[in] ev The event context. * * @param[in] msg_ctx The messaging context. */ void delete_and_reload_printers(struct tevent_context *ev, struct messaging_context *msg_ctx) { int n_services; int pnum; int snum; const char *pname; bool ok; time_t pcap_last_update; TALLOC_CTX *frame = talloc_stackframe(); ok = pcap_cache_loaded(&pcap_last_update); if (!ok) { DEBUG(1, ("pcap cache not loaded\n")); talloc_free(frame); return; } if (reload_last_pcap_time == pcap_last_update) { DEBUG(5, ("skipping printer reload, already up to date.\n")); talloc_free(frame); return; } reload_last_pcap_time = pcap_last_update; /* Get pcap printers updated */ load_printers(ev, msg_ctx); n_services = lp_numservices(); pnum = lp_servicenumber(PRINTERS_NAME); DEBUG(10, ("reloading printer services from pcap cache\n")); /* * Add default config for printers added to smb.conf file and remove * stale printers */ for (snum = 0; snum < n_services; snum++) { /* avoid removing PRINTERS_NAME */ if (snum == pnum) { continue; } /* skip no-printer services */ if (!snum_is_shared_printer(snum)) { continue; } pname = lp_printername(frame, snum); /* check printer, but avoid removing non-autoloaded printers */ if (lp_autoloaded(snum) && !pcap_printername_ok(pname)) { lp_killservice(snum); } } /* Make sure deleted printers are gone */ load_printers(ev, msg_ctx); talloc_free(frame); }
static int key_printers_fetch_keys( const char *key, REGSUBKEY_CTR *subkeys ) { int n_services = lp_numservices(); int snum; fstring sname; int i; int num_subkeys = 0; char *printers_key; char *printername, *printerdatakey; NT_PRINTER_INFO_LEVEL *printer = NULL; fstring *subkey_names = NULL; DEBUG(10,("key_printers_fetch_keys: key=>[%s]\n", key ? key : "NULL" )); printers_key = strip_printers_prefix( key ); if ( !printers_key ) { /* enumerate all printers */ for (snum=0; snum<n_services; snum++) { if ( !(lp_snum_ok(snum) && lp_print_ok(snum) ) ) continue; /* don't report the [printers] share */ if ( strequal( lp_servicename(snum), PRINTERS_NAME ) ) continue; fstrcpy( sname, lp_servicename(snum) ); regsubkey_ctr_addkey( subkeys, sname ); } num_subkeys = regsubkey_ctr_numkeys( subkeys ); goto done; } /* get information for a specific printer */ if (!reg_split_path( printers_key, &printername, &printerdatakey )) { return -1; } /* validate the printer name */ for (snum=0; snum<n_services; snum++) { if ( !lp_snum_ok(snum) || !lp_print_ok(snum) ) continue; if (strequal( lp_servicename(snum), printername ) ) break; } if ( snum>=n_services || !W_ERROR_IS_OK( get_a_printer(NULL, &printer, 2, printername) ) ) { return -1; } num_subkeys = get_printer_subkeys( printer->info_2->data, printerdatakey?printerdatakey:"", &subkey_names ); for ( i=0; i<num_subkeys; i++ ) regsubkey_ctr_addkey( subkeys, subkey_names[i] ); free_a_printer( &printer, 2 ); /* no other subkeys below here */ done: SAFE_FREE( subkey_names ); return num_subkeys; }
/** * @brief Purge stale printers and reload from pre-populated pcap cache. * * This function should normally only be called as a callback on a successful * pcap_cache_reload(). * * This function can cause DELETION of printers and drivers from our registry, * so calling it on a failed pcap reload may REMOVE permanently all printers * and drivers. * * @param[in] ev The event context. * * @param[in] msg_ctx The messaging context. */ static void delete_and_reload_printers_full(struct tevent_context *ev, struct messaging_context *msg_ctx) { struct auth_session_info *session_info = NULL; struct spoolss_PrinterInfo2 *pinfo2 = NULL; int n_services; int pnum; int snum; const char *pname; const char *sname; NTSTATUS status; n_services = lp_numservices(); pnum = lp_servicenumber(PRINTERS_NAME); status = make_session_info_system(talloc_tos(), &session_info); if (!NT_STATUS_IS_OK(status)) { DEBUG(3, ("reload_printers: " "Could not create system session_info\n")); /* can't remove stale printers before we * are fully initilized */ return; } /* * Add default config for printers added to smb.conf file and remove * stale printers */ for (snum = 0; snum < n_services; snum++) { /* avoid removing PRINTERS_NAME */ if (snum == pnum) { continue; } /* skip no-printer services */ if (!snum_is_shared_printer(snum)) { continue; } sname = lp_const_servicename(snum); pname = lp_printername(session_info, snum); /* check printer, but avoid removing non-autoloaded printers */ if (lp_autoloaded(snum) && !pcap_printername_ok(pname)) { DEBUG(3, ("removing stale printer %s\n", pname)); if (is_printer_published(session_info, session_info, msg_ctx, NULL, lp_servicename(session_info, snum), &pinfo2)) { nt_printer_publish(session_info, session_info, msg_ctx, pinfo2, DSPRINT_UNPUBLISH); TALLOC_FREE(pinfo2); } nt_printer_remove(session_info, session_info, msg_ctx, pname); } else { DEBUG(8, ("Adding default registry entry for printer " "[%s], if it doesn't exist.\n", sname)); nt_printer_add(session_info, session_info, msg_ctx, sname); } } /* finally, purge old snums */ delete_and_reload_printers(); TALLOC_FREE(session_info); }
WERROR check_published_printers(struct messaging_context *msg_ctx) { ADS_STATUS ads_rc; ADS_STRUCT *ads = NULL; int snum; int n_services = lp_numservices(); TALLOC_CTX *tmp_ctx = NULL; struct auth_serversupplied_info *session_info = NULL; struct spoolss_PrinterInfo2 *pinfo2; NTSTATUS status; WERROR result; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) return WERR_NOMEM; ads = ads_init(lp_realm(), lp_workgroup(), NULL); if (!ads) { DEBUG(3, ("ads_init() failed\n")); return WERR_SERVER_UNAVAILABLE; } setenv(KRB5_ENV_CCNAME, "MEMORY:prtpub_cache", 1); SAFE_FREE(ads->auth.password); ads->auth.password = secrets_fetch_machine_password(lp_workgroup(), NULL, NULL); /* ads_connect() will find the DC for us */ ads_rc = ads_connect(ads); if (!ADS_ERR_OK(ads_rc)) { DEBUG(3, ("ads_connect failed: %s\n", ads_errstr(ads_rc))); result = WERR_ACCESS_DENIED; goto done; } status = make_session_info_system(tmp_ctx, &session_info); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("check_published_printers: " "Could not create system session_info\n")); result = WERR_ACCESS_DENIED; goto done; } for (snum = 0; snum < n_services; snum++) { if (!lp_snum_ok(snum) || !lp_print_ok(snum)) { continue; } result = winreg_get_printer(tmp_ctx, session_info, msg_ctx, lp_servicename(snum), &pinfo2); if (!W_ERROR_IS_OK(result)) { continue; } if (pinfo2->attributes & PRINTER_ATTRIBUTE_PUBLISHED) { nt_printer_publish_ads(msg_ctx, ads, pinfo2); } TALLOC_FREE(pinfo2); } result = WERR_OK; done: ads_destroy(&ads); ads_kdestroy("MEMORY:prtpub_cache"); talloc_free(tmp_ctx); return result; }
int main(int argc, const char *argv[]) { const char *config_file = get_dyn_CONFIGFILE(); int s; static int silent_mode = False; static int show_all_parameters = False; int ret = 0; poptContext pc; static char *parameter_name = NULL; static const char *section_name = NULL; const char *cname; const char *caddr; static int show_defaults; static int skip_logic_checks = 0; struct poptOption long_options[] = { POPT_AUTOHELP {"suppress-prompt", 's', POPT_ARG_VAL, &silent_mode, 1, "Suppress prompt for enter"}, {"verbose", 'v', POPT_ARG_NONE, &show_defaults, 1, "Show default options too"}, {"skip-logic-checks", 'l', POPT_ARG_NONE, &skip_logic_checks, 1, "Skip the global checks"}, {"show-all-parameters", '\0', POPT_ARG_VAL, &show_all_parameters, True, "Show the parameters, type, possible values" }, {"parameter-name", '\0', POPT_ARG_STRING, ¶meter_name, 0, "Limit testparm to a named parameter" }, {"section-name", '\0', POPT_ARG_STRING, §ion_name, 0, "Limit testparm to a named section" }, POPT_COMMON_VERSION POPT_COMMON_DEBUGLEVEL POPT_COMMON_OPTION POPT_TABLEEND }; TALLOC_CTX *frame = talloc_stackframe(); load_case_tables(); /* * Set the default debug level to 2. * Allow it to be overridden by the command line, * not by smb.conf. */ lp_set_cmdline("log level", "2"); pc = poptGetContext(NULL, argc, argv, long_options, POPT_CONTEXT_KEEP_FIRST); poptSetOtherOptionHelp(pc, "[OPTION...] <config-file> [host-name] [host-ip]"); while(poptGetNextOpt(pc) != -1); if (show_all_parameters) { show_parameter_list(); exit(0); } setup_logging(poptGetArg(pc), DEBUG_STDERR); if (poptPeekArg(pc)) config_file = poptGetArg(pc); cname = poptGetArg(pc); caddr = poptGetArg(pc); poptFreeContext(pc); if ( cname && ! caddr ) { printf ( "ERROR: You must specify both a machine name and an IP address.\n" ); ret = 1; goto done; } fprintf(stderr,"Load smb config files from %s\n",config_file); if (!lp_load_with_registry_shares(config_file,False,True,False,True)) { fprintf(stderr,"Error loading services.\n"); ret = 1; goto done; } fprintf(stderr,"Loaded services file OK.\n"); if (skip_logic_checks == 0) { ret = do_global_checks(); } for (s=0;s<1000;s++) { if (VALID_SNUM(s)) if (strlen(lp_servicename(talloc_tos(), s)) > 12) { fprintf(stderr, "WARNING: You have some share names that are longer than 12 characters.\n" ); fprintf(stderr, "These may not be accessible to some older clients.\n" ); fprintf(stderr, "(Eg. Windows9x, WindowsMe, and smbclient prior to Samba 3.0.)\n" ); break; } } for (s=0;s<1000;s++) { if (VALID_SNUM(s) && (skip_logic_checks == 0)) { do_per_share_checks(s); } } if (!section_name && !parameter_name) { fprintf(stderr, "Server role: %s\n\n", server_role_str(lp_server_role())); } if (!cname) { if (!silent_mode) { fprintf(stderr,"Press enter to see a dump of your service definitions\n"); fflush(stdout); getc(stdin); } if (parameter_name || section_name) { bool isGlobal = False; s = GLOBAL_SECTION_SNUM; if (!section_name) { section_name = GLOBAL_NAME; isGlobal = True; } else if ((isGlobal=!strwicmp(section_name, GLOBAL_NAME)) == 0 && (s=lp_servicenumber(section_name)) == -1) { fprintf(stderr,"Unknown section %s\n", section_name); ret = 1; goto done; } if (parameter_name) { if (!dump_a_parameter( s, parameter_name, stdout, isGlobal)) { fprintf(stderr,"Parameter %s unknown for section %s\n", parameter_name, section_name); ret = 1; goto done; } } else { if (isGlobal == True) lp_dump(stdout, show_defaults, 0); else lp_dump_one(stdout, show_defaults, s); } goto done; } lp_dump(stdout, show_defaults, lp_numservices()); } if(cname && caddr){ /* this is totally ugly, a real `quick' hack */ for (s=0;s<1000;s++) { if (VALID_SNUM(s)) { if (allow_access(lp_hosts_deny(-1), lp_hosts_allow(-1), cname, caddr) && allow_access(lp_hosts_deny(s), lp_hosts_allow(s), cname, caddr)) { fprintf(stderr,"Allow connection from %s (%s) to %s\n", cname,caddr,lp_servicename(talloc_tos(), s)); } else { fprintf(stderr,"Deny connection from %s (%s) to %s\n", cname,caddr,lp_servicename(talloc_tos(), s)); } } } } done: gfree_loadparm(); TALLOC_FREE(frame); return ret; }
static int do_share_checks(struct loadparm_context *lp_ctx, const char *cname, const char *caddr, bool silent_mode, bool show_defaults, const char *section_name, const char *parameter_name) { int ret = 0; int s; for (s=0;s<lp_numservices(lp_ctx);s++) { struct loadparm_service *service = lp_servicebynum(lp_ctx, s); if (service != NULL) if (strlen(lp_servicename(lp_servicebynum(lp_ctx, s))) > 12) { fprintf(stderr, "WARNING: You have some share names that are longer than 12 characters.\n" ); fprintf(stderr, "These may not be accessible to some older clients.\n" ); fprintf(stderr, "(Eg. Windows9x, WindowsMe, and not listed in smbclient in Samba 3.0.)\n" ); break; } } for (s=0;s<lp_numservices(lp_ctx);s++) { struct loadparm_service *service = lp_servicebynum(lp_ctx, s); if (service != NULL) { const char **deny_list = lp_hostsdeny(service, lp_default_service(lp_ctx)); const char **allow_list = lp_hostsallow(service, lp_default_service(lp_ctx)); int i; if(deny_list) { for (i=0; deny_list[i]; i++) { char *hasstar = strchr_m(deny_list[i], '*'); char *hasquery = strchr_m(deny_list[i], '?'); if(hasstar || hasquery) { fprintf(stderr,"Invalid character %c in hosts deny list (%s) for service %s.\n", hasstar ? *hasstar : *hasquery, deny_list[i], lp_servicename(service) ); } } } if(allow_list) { for (i=0; allow_list[i]; i++) { char *hasstar = strchr_m(allow_list[i], '*'); char *hasquery = strchr_m(allow_list[i], '?'); if(hasstar || hasquery) { fprintf(stderr,"Invalid character %c in hosts allow list (%s) for service %s.\n", hasstar ? *hasstar : *hasquery, allow_list[i], lp_servicename(service) ); } } } } } if (!cname) { if (!silent_mode) { fprintf(stderr,"Press enter to see a dump of your service definitions\n"); fflush(stdout); getc(stdin); } if (section_name != NULL || parameter_name != NULL) { struct loadparm_service *service = NULL; if (!section_name) { section_name = GLOBAL_NAME; service = NULL; } else if ((!strwicmp(section_name, GLOBAL_NAME)) == 0 && (service=lp_service(lp_ctx, section_name)) == NULL) { fprintf(stderr,"Unknown section %s\n", section_name); return(1); } if (!parameter_name) { lp_dump_one(stdout, show_defaults, service, lp_default_service(lp_ctx)); } else { ret = !lp_dump_a_parameter(lp_ctx, service, parameter_name, stdout); } } else { lp_dump(lp_ctx, stdout, show_defaults, lp_numservices(lp_ctx)); } return(ret); } if(cname && caddr){ /* this is totally ugly, a real `quick' hack */ for (s=0;s<lp_numservices(lp_ctx);s++) { struct loadparm_service *service = lp_servicebynum(lp_ctx, s); if (service != NULL) { if (allow_access(NULL, lp_hostsdeny(NULL, lp_default_service(lp_ctx)), lp_hostsallow(NULL, lp_default_service(lp_ctx)), cname, caddr) && allow_access(NULL, lp_hostsdeny(service, lp_default_service(lp_ctx)), lp_hostsallow(service, lp_default_service(lp_ctx)), cname, caddr)) { fprintf(stderr,"Allow connection from %s (%s) to %s\n", cname,caddr,lp_servicename(service)); } else { fprintf(stderr,"Deny connection from %s (%s) to %s\n", cname,caddr,lp_servicename(service)); } } } } return ret; }