diff options
-rw-r--r-- | source3/include/proto.h | 15 | ||||
-rw-r--r-- | source3/printing/nt_printing.c | 309 | ||||
-rw-r--r-- | source3/rpc_server/srv_spoolss_nt.c | 25 | ||||
-rw-r--r-- | source3/smbd/server_reload.c | 27 |
4 files changed, 257 insertions, 119 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h index 4d0536832c..738559b748 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -4753,14 +4753,15 @@ int add_new_printer_key( NT_PRINTER_DATA *data, const char *name ); int delete_printer_key( NT_PRINTER_DATA *data, const char *name ); int lookup_printerkey( NT_PRINTER_DATA *data, const char *name ); int get_printer_subkeys( NT_PRINTER_DATA *data, const char* key, fstring **subkeys ); -WERROR nt_printer_publish(Printer_entry *print_hnd, int snum, int action); +WERROR nt_printer_publish(TALLOC_CTX *mem_ctx, + struct auth_serversupplied_info *server_info, + struct spoolss_PrinterInfo2 *pinfo2, + int action); WERROR check_published_printers(void); -bool is_printer_published(Printer_entry *print_hnd, int snum, - struct GUID *guid); -WERROR nt_printer_publish(Printer_entry *print_hnd, int snum, int action); -WERROR check_published_printers(void); -bool is_printer_published(Printer_entry *print_hnd, int snum, - struct GUID *guid); +bool is_printer_published(TALLOC_CTX *mem_ctx, + struct auth_serversupplied_info *server_info, + char *servername, char *printer, struct GUID *guid, + struct spoolss_PrinterInfo2 **info2); WERROR delete_all_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, const char *key ); WERROR delete_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, const char *key, const char *value ); WERROR add_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, const char *key, const char *value, diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c index 0369ce8ed1..e4694ebd96 100644 --- a/source3/printing/nt_printing.c +++ b/source3/printing/nt_printing.c @@ -2660,14 +2660,19 @@ static void map_single_multi_sz_into_ctr(struct regval_ctr *ctr, const char *val } /**************************************************************************** - * Map the NT_PRINTER_INFO_LEVEL_2 data into DsSpooler keys for publishing. + * Map spoolss_PrinterInfo2 data into DsSpooler keys for publishing. * - * @param info2 NT_PRINTER_INFO_LEVEL_2 describing printer - gets modified - * @return bool indicating success or failure + * @param mem_ctx allocation context + * @param info2 spoolss_PrinterInfo2 describing printer + * @param pdata the talloced printer data + * @return bool indicating success or failure ***************************************************************************/ -static bool map_nt_printer_info2_to_dsspooler(NT_PRINTER_INFO_LEVEL_2 *info2) +static bool map_nt_printer_info2_to_dsspooler(TALLOC_CTX *mem_ctx, + struct spoolss_PrinterInfo2 *info2, + NT_PRINTER_DATA **pdata) { + NT_PRINTER_DATA *data; struct regval_ctr *ctr = NULL; fstring longname; const char *dnssuffix; @@ -2675,9 +2680,12 @@ static bool map_nt_printer_info2_to_dsspooler(NT_PRINTER_INFO_LEVEL_2 *info2) const char *ascii_str; int i; - if ((i = lookup_printerkey(info2->data, SPOOL_DSSPOOLER_KEY)) < 0) - i = add_new_printer_key(info2->data, SPOOL_DSSPOOLER_KEY); - ctr = info2->data->keys[i].values; + data = talloc_zero(mem_ctx, NT_PRINTER_DATA); + if (!data) return false; + + /* init data */ + i = add_new_printer_key(data, SPOOL_DSSPOOLER_KEY); + ctr = data->keys[i].values; map_sz_into_ctr(ctr, SPOOL_REG_PRINTERNAME, info2->sharename); map_sz_into_ctr(ctr, SPOOL_REG_SHORTSERVERNAME, global_myname()); @@ -2696,6 +2704,7 @@ static bool map_nt_printer_info2_to_dsspooler(NT_PRINTER_INFO_LEVEL_2 *info2) map_sz_into_ctr(ctr, SPOOL_REG_SERVERNAME, longname); if (asprintf(&allocated_string, "\\\\%s\\%s", longname, info2->sharename) == -1) { + talloc_free(data); return false; } map_sz_into_ctr(ctr, SPOOL_REG_UNCNAME, allocated_string); @@ -2730,34 +2739,65 @@ static bool map_nt_printer_info2_to_dsspooler(NT_PRINTER_INFO_LEVEL_2 *info2) } map_sz_into_ctr(ctr, SPOOL_REG_PRINTSPOOLING, ascii_str); - return True; + *pdata = data; + return true; } /***************************************************************** ****************************************************************/ -static void store_printer_guid(NT_PRINTER_INFO_LEVEL_2 *info2, - struct GUID guid) +static void store_printer_guid(const char *printer, struct GUID guid) { - int i; - struct regval_ctr *ctr=NULL; + TALLOC_CTX *tmp_ctx; + struct auth_serversupplied_info *server_info = NULL; + const char *guid_str; + DATA_BLOB blob; + NTSTATUS status; + WERROR result; + + tmp_ctx = talloc_new(NULL); + if (!tmp_ctx) { + DEBUG(0, ("store_printer_guid: Out of memory?!\n")); + return; + } - /* find the DsSpooler key */ - if ((i = lookup_printerkey(info2->data, SPOOL_DSSPOOLER_KEY)) < 0) - i = add_new_printer_key(info2->data, SPOOL_DSSPOOLER_KEY); - ctr = info2->data->keys[i].values; + status = make_server_info_system(tmp_ctx, &server_info); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("store_printer_guid: " + "Could not create system server_info\n")); + goto done; + } - regval_ctr_delvalue(ctr, "objectGUID"); + guid_str = GUID_string(tmp_ctx, &guid); + if (!guid_str) { + DEBUG(0, ("store_printer_guid: Out of memory?!\n")); + goto done; + } /* We used to store this as a REG_BINARY but that causes Vista to whine */ - regval_ctr_addvalue_sz(ctr, "objectGUID", - GUID_string(talloc_tos(), &guid)); + if (!push_reg_sz(tmp_ctx, &blob, guid_str)) { + DEBUG(0, ("store_printer_guid: " + "Could not marshall string %s for objectGUID\n", + guid_str)); + goto done; + } + + result = winreg_set_printer_dataex(tmp_ctx, server_info, printer, + SPOOL_DSSPOOLER_KEY, "objectGUID", + REG_SZ, blob.data, blob.length); + if (!W_ERROR_IS_OK(result)) { + DEBUG(0, ("store_printer_guid: " + "Failed to store GUID for printer %s\n", printer)); + } + +done: + talloc_free(tmp_ctx); } static WERROR nt_printer_publish_ads(ADS_STRUCT *ads, - NT_PRINTER_INFO_LEVEL *printer) + struct spoolss_PrinterInfo2 *pinfo2) { ADS_STATUS ads_rc; LDAPMessage *res; @@ -2769,6 +2809,8 @@ static WERROR nt_printer_publish_ads(ADS_STRUCT *ads, struct GUID guid; WERROR win_rc = WERR_OK; size_t converted_size; + NT_PRINTER_DATA *pdata; + const char *printer = pinfo2->sharename; /* build the ads mods */ ctx = talloc_init("nt_printer_publish_ads"); @@ -2776,7 +2818,12 @@ static WERROR nt_printer_publish_ads(ADS_STRUCT *ads, return WERR_NOMEM; } - DEBUG(5, ("publishing printer %s\n", printer->info_2->printername)); + DEBUG(5, ("publishing printer %s\n", printer)); + + if (!map_nt_printer_info2_to_dsspooler(ctx, pinfo2, &pdata)) { + TALLOC_FREE(ctx); + return WERR_SERVER_UNAVAILABLE; + } /* figure out where to publish */ ads_find_machine_acct(ads, &res, global_myname()); @@ -2819,7 +2866,7 @@ static WERROR nt_printer_publish_ads(ADS_STRUCT *ads, TALLOC_FREE(ctx); return WERR_SERVER_UNAVAILABLE; } - sharename_escaped = escape_rdn_val_string_alloc(printer->info_2->sharename); + sharename_escaped = escape_rdn_val_string_alloc(printer); if (!sharename_escaped) { SAFE_FREE(srv_cn_escaped); TALLOC_FREE(ctx); @@ -2839,9 +2886,8 @@ static WERROR nt_printer_publish_ads(ADS_STRUCT *ads, return WERR_NOMEM; } - get_local_printer_publishing_data(ctx, &mods, printer->info_2->data); - ads_mod_str(ctx, &mods, SPOOL_REG_PRINTERNAME, - printer->info_2->sharename); + get_local_printer_publishing_data(ctx, &mods, pdata); + ads_mod_str(ctx, &mods, SPOOL_REG_PRINTERNAME, printer); /* publish it */ ads_rc = ads_mod_printer_entry(ads, prt_dn, ctx, &mods); @@ -2853,16 +2899,17 @@ static WERROR nt_printer_publish_ads(ADS_STRUCT *ads, ads_rc = ads_add_printer_entry(ads, prt_dn, ctx, &mods); } - if (!ADS_ERR_OK(ads_rc)) - DEBUG(3, ("error publishing %s: %s\n", printer->info_2->sharename, ads_errstr(ads_rc))); + if (!ADS_ERR_OK(ads_rc)) { + DEBUG(3, ("error publishing %s: %s\n", + printer, ads_errstr(ads_rc))); + } /* retreive the guid and store it locally */ if (ADS_ERR_OK(ads_search_dn(ads, &res, prt_dn, attrs))) { ZERO_STRUCT(guid); ads_pull_guid(ads, res, &guid); ads_msgfree(ads, res); - store_printer_guid(printer->info_2, guid); - win_rc = mod_a_printer(printer, 2); + store_printer_guid(printer, guid); } TALLOC_FREE(ctx); @@ -2870,17 +2917,17 @@ static WERROR nt_printer_publish_ads(ADS_STRUCT *ads, } static WERROR nt_printer_unpublish_ads(ADS_STRUCT *ads, - NT_PRINTER_INFO_LEVEL *printer) + const char *printer) { ADS_STATUS ads_rc; LDAPMessage *res = NULL; char *prt_dn = NULL; - DEBUG(5, ("unpublishing printer %s\n", printer->info_2->printername)); + DEBUG(5, ("unpublishing printer %s\n", printer)); /* remove the printer from the directory */ ads_rc = ads_find_printer_on_server(ads, &res, - printer->info_2->sharename, global_myname()); + printer, global_myname()); if (ADS_ERR_OK(ads_rc) && res && ads_count_replies(ads, res)) { prt_dn = ads_get_dn(ads, talloc_tos(), res); @@ -2901,46 +2948,54 @@ static WERROR nt_printer_unpublish_ads(ADS_STRUCT *ads, /**************************************************************************** * Publish a printer in the directory * - * @param snum describing printer service + * @param mem_ctx memory context + * @param server_info server_info to access winreg pipe + * @param pinfo2 printer information + * @param action publish/unpublish action * @return WERROR indicating status of publishing ***************************************************************************/ -WERROR nt_printer_publish(Printer_entry *print_hnd, int snum, int action) +WERROR nt_printer_publish(TALLOC_CTX *mem_ctx, + struct auth_serversupplied_info *server_info, + struct spoolss_PrinterInfo2 *pinfo2, + int action) { + uint32_t info2_mask = SPOOLSS_PRINTER_INFO_ATTRIBUTES; + struct spoolss_SetPrinterInfo2 *sinfo2; ADS_STATUS ads_rc; ADS_STRUCT *ads = NULL; - NT_PRINTER_INFO_LEVEL *printer = NULL; WERROR win_rc; - win_rc = get_a_printer(print_hnd, &printer, 2, lp_servicename(snum)); - if (!W_ERROR_IS_OK(win_rc)) - goto done; + sinfo2 = talloc_zero(mem_ctx, struct spoolss_SetPrinterInfo2); + if (!sinfo2) { + return WERR_NOMEM; + } switch (action) { case DSPRINT_PUBLISH: case DSPRINT_UPDATE: - /* set the DsSpooler info and attributes */ - if (!(map_nt_printer_info2_to_dsspooler(printer->info_2))) { - win_rc = WERR_NOMEM; - goto done; - } - - printer->info_2->attributes |= PRINTER_ATTRIBUTE_PUBLISHED; + pinfo2->attributes |= PRINTER_ATTRIBUTE_PUBLISHED; break; case DSPRINT_UNPUBLISH: - printer->info_2->attributes ^= PRINTER_ATTRIBUTE_PUBLISHED; + pinfo2->attributes ^= PRINTER_ATTRIBUTE_PUBLISHED; break; default: win_rc = WERR_NOT_SUPPORTED; goto done; } - win_rc = mod_a_printer(printer, 2); + sinfo2->attributes = pinfo2->attributes; + + win_rc = winreg_update_printer(mem_ctx, server_info, + pinfo2->sharename, info2_mask, + sinfo2, NULL, NULL); if (!W_ERROR_IS_OK(win_rc)) { DEBUG(3, ("err %d saving data\n", W_ERROR_V(win_rc))); goto done; } + TALLOC_FREE(sinfo2); + ads = ads_init(lp_realm(), lp_workgroup(), NULL); if (!ads) { DEBUG(3, ("ads_init() failed\n")); @@ -2963,15 +3018,14 @@ WERROR nt_printer_publish(Printer_entry *print_hnd, int snum, int action) switch (action) { case DSPRINT_PUBLISH: case DSPRINT_UPDATE: - win_rc = nt_printer_publish_ads(ads, printer); + win_rc = nt_printer_publish_ads(ads, pinfo2); break; case DSPRINT_UNPUBLISH: - win_rc = nt_printer_unpublish_ads(ads, printer); + win_rc = nt_printer_unpublish_ads(ads, pinfo2->sharename); break; } done: - free_a_printer(&printer, 2); ads_destroy(&ads); return win_rc; } @@ -2982,7 +3036,14 @@ WERROR check_published_printers(void) ADS_STRUCT *ads = NULL; int snum; int n_services = lp_numservices(); - NT_PRINTER_INFO_LEVEL *printer = NULL; + TALLOC_CTX *tmp_ctx = NULL; + struct auth_serversupplied_info *server_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) { @@ -2998,86 +3059,118 @@ WERROR check_published_printers(void) ads_rc = ads_connect(ads); if (!ADS_ERR_OK(ads_rc)) { DEBUG(3, ("ads_connect failed: %s\n", ads_errstr(ads_rc))); - ads_destroy(&ads); - ads_kdestroy("MEMORY:prtpub_cache"); - return WERR_ACCESS_DENIED; + result = WERR_ACCESS_DENIED; + goto done; + } + + status = make_server_info_system(tmp_ctx, &server_info); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("check_published_printers: " + "Could not create system server_info\n")); + result = WERR_ACCESS_DENIED; + goto done; } for (snum = 0; snum < n_services; snum++) { - if (!(lp_snum_ok(snum) && lp_print_ok(snum))) + if (!lp_snum_ok(snum) || !lp_print_ok(snum)) { + continue; + } + + result = winreg_get_printer(tmp_ctx, server_info, NULL, + lp_servicename(snum), &pinfo2); + if (!W_ERROR_IS_OK(result)) { continue; + } - if (W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, - lp_servicename(snum))) && - (printer->info_2->attributes & PRINTER_ATTRIBUTE_PUBLISHED)) - nt_printer_publish_ads(ads, printer); + if (pinfo2->attributes & PRINTER_ATTRIBUTE_PUBLISHED) { + nt_printer_publish_ads(ads, pinfo2); + } - free_a_printer(&printer, 2); + TALLOC_FREE(pinfo2); } + result = WERR_OK; +done: ads_destroy(&ads); ads_kdestroy("MEMORY:prtpub_cache"); - return WERR_OK; + talloc_free(tmp_ctx); + return result; } -bool is_printer_published(Printer_entry *print_hnd, int snum, - struct GUID *guid) +bool is_printer_published(TALLOC_CTX *mem_ctx, + struct auth_serversupplied_info *server_info, + char *servername, char *printer, struct GUID *guid, + struct spoolss_PrinterInfo2 **info2) { - NT_PRINTER_INFO_LEVEL *printer = NULL; - struct regval_ctr *ctr; - struct regval_blob *guid_val; - WERROR win_rc; - int i; - bool ret = False; - DATA_BLOB blob; + struct spoolss_PrinterInfo2 *pinfo2 = NULL; + enum winreg_Type type; + uint8_t *data; + uint32_t data_size; + WERROR result; + NTSTATUS status; - win_rc = get_a_printer(print_hnd, &printer, 2, lp_servicename(snum)); + result = winreg_get_printer(mem_ctx, server_info, + servername, printer, &pinfo2); + if (!W_ERROR_IS_OK(result)) { + return false; + } - if (!W_ERROR_IS_OK(win_rc) || - !(printer->info_2->attributes & PRINTER_ATTRIBUTE_PUBLISHED) || - ((i = lookup_printerkey(printer->info_2->data, SPOOL_DSSPOOLER_KEY)) < 0) || - !(ctr = printer->info_2->data->keys[i].values) || - !(guid_val = regval_ctr_getvalue(ctr, "objectGUID"))) - { - free_a_printer(&printer, 2); - return False; + if (!(pinfo2->attributes & PRINTER_ATTRIBUTE_PUBLISHED)) { + TALLOC_FREE(pinfo2); + return false; + } + + if (!guid) { + goto done; } /* fetching printer guids really ought to be a separate function. */ - if ( guid ) { - char *guid_str; + result = winreg_get_printer_dataex(mem_ctx, server_info, printer, + SPOOL_DSSPOOLER_KEY, "objectGUID", + &type, &data, &data_size); + if (!W_ERROR_IS_OK(result)) { + TALLOC_FREE(pinfo2); + return false; + } - /* We used to store the guid as REG_BINARY, then swapped - to REG_SZ for Vista compatibility so check for both */ + /* We used to store the guid as REG_BINARY, then swapped + to REG_SZ for Vista compatibility so check for both */ - switch ( regval_type(guid_val) ){ - case REG_SZ: - blob = data_blob_const(regval_data_p(guid_val), - regval_size(guid_val)); - pull_reg_sz(talloc_tos(), &blob, (const char **)&guid_str); - ret = NT_STATUS_IS_OK(GUID_from_string( guid_str, guid )); - talloc_free(guid_str); - break; - case REG_BINARY: - if ( regval_size(guid_val) != sizeof(struct GUID) ) { - ret = False; - break; - } - memcpy(guid, regval_data_p(guid_val), sizeof(struct GUID)); - break; - default: - DEBUG(0,("is_printer_published: GUID value stored as " - "invaluid type (%d)\n", regval_type(guid_val) )); - break; + switch (type) { + case REG_SZ: + status = GUID_from_string((char *)data, guid); + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(pinfo2); + return false; + } + break; + + case REG_BINARY: + if (data_size != sizeof(struct GUID)) { + TALLOC_FREE(pinfo2); + return false; } + memcpy(guid, data, sizeof(struct GUID)); + break; + default: + DEBUG(0,("is_printer_published: GUID value stored as " + "invaluid type (%d)\n", type)); + break; } - free_a_printer(&printer, 2); - return ret; +done: + if (info2) { + *info2 = talloc_move(mem_ctx, &pinfo2); + } + talloc_free(pinfo2); + return true; } #else -WERROR nt_printer_publish(Printer_entry *print_hnd, int snum, int action) +WERROR nt_printer_publish(TALLOC_CTX *mem_ctx, + struct auth_serversupplied_info *server_info, + struct spoolss_PrinterInfo2 *pinfo2, + int action) { return WERR_OK; } @@ -3087,8 +3180,10 @@ WERROR check_published_printers(void) return WERR_OK; } -bool is_printer_published(Printer_entry *print_hnd, int snum, - struct GUID *guid) +bool is_printer_published(TALLOC_CTX *mem_ctx, + struct auth_serversupplied_info *server_info, + char *servername, char *printer, struct GUID *guid, + struct spoolss_PrinterInfo2 **info2) { return False; } diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c index ab1678ffef..6c1eab4168 100644 --- a/source3/rpc_server/srv_spoolss_nt.c +++ b/source3/rpc_server/srv_spoolss_nt.c @@ -3706,9 +3706,19 @@ static WERROR construct_printer_info7(TALLOC_CTX *mem_ctx, struct spoolss_PrinterInfo7 *r, int snum) { + struct auth_serversupplied_info *server_info; struct GUID guid; + NTSTATUS status; + + status = make_server_info_system(mem_ctx, &server_info); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("construct_printer_info7: " + "Could not create system server_info\n")); + return WERR_NOMEM; + } - if (is_printer_published(print_hnd, snum, &guid)) { + if (is_printer_published(mem_ctx, server_info, print_hnd->servername, + lp_servicename(snum), &guid, NULL)) { r->guid = talloc_strdup_upper(mem_ctx, GUID_string2(mem_ctx, &guid)); r->action = DSPRINT_PUBLISH; } else { @@ -3717,6 +3727,7 @@ static WERROR construct_printer_info7(TALLOC_CTX *mem_ctx, } W_ERROR_HAVE_NO_MEMORY(r->guid); + TALLOC_FREE(server_info); return WERR_OK; } @@ -5746,6 +5757,8 @@ static WERROR publish_or_unpublish_printer(pipes_struct *p, struct spoolss_SetPrinterInfo7 *info7) { #ifdef HAVE_ADS + struct spoolss_PrinterInfo2 *pinfo2 = NULL; + WERROR result; int snum; Printer_entry *Printer; @@ -5763,8 +5776,16 @@ static WERROR publish_or_unpublish_printer(pipes_struct *p, if (!get_printer_snum(p, handle, &snum, NULL)) return WERR_BADFID; - nt_printer_publish(Printer, snum, info7->action); + result = winreg_get_printer(p->mem_ctx, p->server_info, + Printer->servername, + lp_servicename(snum), &pinfo2); + if (!W_ERROR_IS_OK(result)) { + return WERR_BADFID; + } + + nt_printer_publish(pinfo2, p->server_info, pinfo2, info7->action); + TALLOC_FREE(pinfo2); return WERR_OK; #else return WERR_UNKNOWN_LEVEL; diff --git a/source3/smbd/server_reload.c b/source3/smbd/server_reload.c index 10f2ac9113..aed1037718 100644 --- a/source3/smbd/server_reload.c +++ b/source3/smbd/server_reload.c @@ -30,15 +30,28 @@ **************************************************************************/ void reload_printers(void) { + struct auth_serversupplied_info *server_info = NULL; + struct spoolss_PrinterInfo2 *pinfo2 = NULL; int snum; int n_services = lp_numservices(); int pnum = lp_servicenumber(PRINTERS_NAME); const char *pname; + NTSTATUS status; + bool skip = false; pcap_cache_reload(); + status = make_server_info_system(talloc_tos(), &server_info); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("reload_printers: " + "Could not create system server_info\n")); + /* can't remove stale printers before we + * are fully initilized */ + skip = true; + } + /* remove stale printers */ - for (snum = 0; snum < n_services; snum++) { + for (snum = 0; skip == false && 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))) @@ -48,14 +61,22 @@ void reload_printers(void) 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, DSPRINT_UNPUBLISH); + if (is_printer_published(server_info, server_info, + NULL, lp_servicename(snum), + NULL, &pinfo2)) { + nt_printer_publish(server_info, + server_info, pinfo2, + DSPRINT_UNPUBLISH); + TALLOC_FREE(pinfo2); + } del_a_printer(pname); lp_killservice(snum); } } load_printers(); + + TALLOC_FREE(server_info); } /**************************************************************************** |