summaryrefslogtreecommitdiff
path: root/source3/printing/nt_printing.c
diff options
context:
space:
mode:
Diffstat (limited to 'source3/printing/nt_printing.c')
-rw-r--r--source3/printing/nt_printing.c281
1 files changed, 169 insertions, 112 deletions
diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c
index c3551c9d90..f047daabee 100644
--- a/source3/printing/nt_printing.c
+++ b/source3/printing/nt_printing.c
@@ -289,6 +289,7 @@ BOOL nt_printing_init(void)
{
static pid_t local_pid;
const char *vstring = "INFO/version";
+ WERROR win_rc;
if (tdb_drivers && tdb_printers && tdb_forms && local_pid == sys_getpid())
return True;
@@ -377,6 +378,10 @@ BOOL nt_printing_init(void)
msgs. This is done in claim_connection() */
+ win_rc = check_published_printers();
+ if (!W_ERROR_IS_OK(win_rc))
+ DEBUG(3, ("error checking published printers: %s\n", W_ERROR_V(win_rc)));
+
return True;
}
@@ -2631,56 +2636,20 @@ static void store_printer_guid(NT_PRINTER_INFO_LEVEL_2 *info2,
(char *) &guid, sizeof(struct uuid));
}
-static WERROR publish_it(NT_PRINTER_INFO_LEVEL *printer)
+static WERROR nt_printer_publish_ads(ADS_STRUCT *ads,
+ NT_PRINTER_INFO_LEVEL *printer)
{
ADS_STATUS ads_rc;
- TALLOC_CTX *ctx = talloc_init("publish_it");
- ADS_MODLIST mods = ads_init_mods(ctx);
+ void *res;
char *prt_dn = NULL, *srv_dn, *srv_cn_0;
char *srv_dn_utf8, **srv_cn_utf8;
- void *res = NULL;
- ADS_STRUCT *ads;
+ TALLOC_CTX *ctx;
+ ADS_MODLIST mods;
const char *attrs[] = {"objectGUID", NULL};
struct uuid guid;
WERROR win_rc = WERR_OK;
- ZERO_STRUCT(guid);
- /* set the DsSpooler info and attributes */
- if (!(map_nt_printer_info2_to_dsspooler(printer->info_2)))
- return WERR_NOMEM;
- printer->info_2->attributes |= PRINTER_ATTRIBUTE_PUBLISHED;
- win_rc = mod_a_printer(*printer, 2);
- if (!W_ERROR_IS_OK(win_rc)) {
- DEBUG(3, ("err %d saving data\n",
- W_ERROR_V(win_rc)));
- return win_rc;
- }
-
- /* Build the ads mods */
- get_local_printer_publishing_data(ctx, &mods,
- &printer->info_2->data);
- ads_mod_str(ctx, &mods, SPOOL_REG_PRINTERNAME,
- printer->info_2->sharename);
-
- /* initial ads structure */
-
- ads = ads_init(NULL, NULL, 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)));
- ads_destroy(&ads);
- return WERR_ACCESS_DENIED;
- }
+ DEBUG(5, ("publishing printer %s\n", printer->info_2->printername));
/* figure out where to publish */
ads_find_machine_acct(ads, &res, global_myname());
@@ -2724,70 +2693,55 @@ static WERROR publish_it(NT_PRINTER_INFO_LEVEL *printer)
SAFE_FREE(srv_dn);
SAFE_FREE(srv_cn_0);
+ /* build the ads mods */
+ ctx = talloc_init("nt_printer_publish_ads");
+ mods = ads_init_mods(ctx);
+
+ get_local_printer_publishing_data(ctx, &mods,
+ &printer->info_2->data);
+ ads_mod_str(ctx, &mods, SPOOL_REG_PRINTERNAME,
+ printer->info_2->sharename);
+
/* publish it */
ads_rc = ads_add_printer_entry(ads, prt_dn, ctx, &mods);
if (LDAP_ALREADY_EXISTS == ads_rc.err.rc)
- ads_rc = ads_mod_printer_entry(ads, prt_dn, ctx,&mods);
+ ads_rc = ads_mod_printer_entry(ads, prt_dn, ctx, &mods);
+ talloc_destroy(ctx);
+
/* 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);
+ win_rc = mod_a_printer(printer, 2);
}
SAFE_FREE(prt_dn);
- ads_destroy(&ads);
-
- return WERR_OK;
+ return win_rc;
}
-WERROR unpublish_it(NT_PRINTER_INFO_LEVEL *printer)
+static WERROR nt_printer_unpublish_ads(ADS_STRUCT *ads,
+ NT_PRINTER_INFO_LEVEL *printer)
{
ADS_STATUS ads_rc;
- ADS_STRUCT *ads;
void *res;
char *prt_dn = NULL;
- WERROR win_rc;
- printer->info_2->attributes ^= PRINTER_ATTRIBUTE_PUBLISHED;
- win_rc = mod_a_printer(*printer, 2);
- if (!W_ERROR_IS_OK(win_rc)) {
- DEBUG(3, ("err %d saving data\n",
- W_ERROR_V(win_rc)));
- return win_rc;
- }
-
- ads = ads_init(NULL, NULL, 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);
+ DEBUG(5, ("unpublishing printer %s\n", printer->info_2->printername));
- /* 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)));
- ads_destroy(&ads);
- return WERR_ACCESS_DENIED;
- }
-
/* remove the printer from the directory */
ads_rc = ads_find_printer_on_server(ads, &res,
printer->info_2->sharename, global_myname());
+
if (ADS_ERR_OK(ads_rc) && ads_count_replies(ads, res)) {
prt_dn = ads_get_dn(ads, res);
- ads_msgfree(ads, res);
ads_rc = ads_del_dn(ads, prt_dn);
ads_memfree(ads, prt_dn);
}
- ads_destroy(&ads);
+ ads_msgfree(ads, res);
return WERR_OK;
}
@@ -2800,30 +2754,134 @@ WERROR unpublish_it(NT_PRINTER_INFO_LEVEL *printer)
WERROR nt_printer_publish(Printer_entry *print_hnd, int snum, int action)
{
+ 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))
- return win_rc;
+ goto done;
- switch(action) {
+ switch (action) {
case SPOOL_DS_PUBLISH:
case SPOOL_DS_UPDATE:
- win_rc = publish_it(printer);
+ /* 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;
break;
case SPOOL_DS_UNPUBLISH:
- win_rc = unpublish_it(printer);
+ printer->info_2->attributes ^= PRINTER_ATTRIBUTE_PUBLISHED;
break;
default:
win_rc = WERR_NOT_SUPPORTED;
+ goto done;
+ }
+
+ win_rc = mod_a_printer(printer, 2);
+ if (!W_ERROR_IS_OK(win_rc)) {
+ DEBUG(3, ("err %d saving data\n", W_ERROR_V(win_rc)));
+ goto done;
}
-
+ ads = ads_init(NULL, NULL, NULL);
+ if (!ads) {
+ DEBUG(3, ("ads_init() failed\n"));
+ win_rc = WERR_SERVER_UNAVAILABLE;
+ goto done;
+ }
+ 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)));
+ win_rc = WERR_ACCESS_DENIED;
+ goto done;
+ }
+
+ switch (action) {
+ case SPOOL_DS_PUBLISH:
+ case SPOOL_DS_UPDATE:
+ win_rc = nt_printer_publish_ads(ads, printer);
+ break;
+ case SPOOL_DS_UNPUBLISH:
+ win_rc = nt_printer_unpublish_ads(ads, printer);
+ break;
+ }
+
+done:
free_a_printer(&printer, 2);
+ ads_destroy(&ads);
return win_rc;
}
+WERROR check_published_printers(void)
+{
+ ADS_STATUS ads_rc;
+ ADS_STRUCT *ads = NULL;
+ void *res = NULL;
+ int snum;
+ int n_services = lp_numservices();
+ NT_PRINTER_INFO_LEVEL *printer = NULL;
+ WERROR win_rc;
+
+ ads = ads_init(NULL, NULL, 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)));
+ ads_destroy(&ads);
+ return WERR_ACCESS_DENIED;
+ }
+
+ for (snum = 0; snum < n_services; snum++) {
+ if (!(lp_snum_ok(snum) && lp_print_ok(snum)))
+ continue;
+
+ if (!W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2,
+ lp_servicename(snum))) ||
+ !(printer->info_2->attributes & PRINTER_ATTRIBUTE_PUBLISHED))
+ goto next;
+
+ DEBUG(5, ("checking directory for printer %s\n", printer->info_2->printername));
+ ads_rc = ads_find_printer_on_server(ads, &res,
+ printer->info_2->sharename, global_myname());
+ if (ADS_ERR_OK(ads_rc) && ads_count_replies(ads, res)) {
+ DEBUG(5, ("printer %s is in directory\n", printer->info_2->printername));
+ goto next;
+ }
+
+ win_rc = nt_printer_publish_ads(ads, printer);
+ if (!W_ERROR_IS_OK(win_rc))
+ DEBUG(3, ("error publishing %s: %s\n", printer->info_2->sharename, W_ERROR_V(win_rc)));
+
+ next:
+ free_a_printer(&printer, 2);
+ ads_msgfree(ads, res);
+ res = NULL;
+ }
+
+ ads_destroy(&ads);
+ return WERR_OK;
+}
+
BOOL is_printer_published(Printer_entry *print_hnd, int snum,
struct uuid *guid)
{
@@ -2833,43 +2891,42 @@ BOOL is_printer_published(Printer_entry *print_hnd, int snum,
WERROR win_rc;
int i;
-
win_rc = get_a_printer(print_hnd, &printer, 2, lp_servicename(snum));
- if (!W_ERROR_IS_OK(win_rc))
- return False;
-
- if (!(printer->info_2->attributes & PRINTER_ATTRIBUTE_PUBLISHED))
- return False;
-
- if ((i = lookup_printerkey(&printer->info_2->data,
- SPOOL_DSSPOOLER_KEY)) < 0)
- return False;
-
- if (!(ctr = &printer->info_2->data.keys[i].values)) {
- return False;
- }
- if (!(guid_val = regval_ctr_getvalue(ctr, "objectGUID"))) {
+ 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 (regval_size(guid_val) == sizeof(struct uuid))
memcpy(guid, regval_data_p(guid_val), sizeof(struct uuid));
+ free_a_printer(&printer, 2);
return True;
}
-
#else
WERROR nt_printer_publish(Printer_entry *print_hnd, int snum, int action)
{
return WERR_OK;
}
+
+WERROR check_published_printers(void)
+{
+ return WERR_OK;
+}
+
BOOL is_printer_published(Printer_entry *print_hnd, int snum,
struct uuid *guid)
{
return False;
}
-#endif
+#endif /* HAVE_ADS */
+
/****************************************************************************
***************************************************************************/
@@ -3391,7 +3448,7 @@ static WERROR get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr, const char *sh
/****************************************************************************
Debugging function, dump at level 6 the struct in the logs.
****************************************************************************/
-static uint32 dump_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
+static uint32 dump_a_printer(NT_PRINTER_INFO_LEVEL *printer, uint32 level)
{
uint32 result;
NT_PRINTER_INFO_LEVEL_2 *info2;
@@ -3401,11 +3458,11 @@ static uint32 dump_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
switch (level) {
case 2:
{
- if (printer.info_2 == NULL)
+ if (printer->info_2 == NULL)
result=5;
else
{
- info2=printer.info_2;
+ info2=printer->info_2;
DEBUGADD(106,("attributes:[%d]\n", info2->attributes));
DEBUGADD(106,("priority:[%d]\n", info2->priority));
@@ -3501,7 +3558,7 @@ static BOOL send_printer_mod_msg( char* printername )
Modify a printer. This is called from SETPRINTERDATA/DELETEPRINTERDATA.
****************************************************************************/
-WERROR mod_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
+WERROR mod_a_printer(NT_PRINTER_INFO_LEVEL *printer, uint32 level)
{
WERROR result;
@@ -3513,8 +3570,8 @@ WERROR mod_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
* get_a_printer()
*/
- invalidate_printer_hnd_cache( printer.info_2->sharename );
- send_printer_mod_msg( printer.info_2->sharename );
+ invalidate_printer_hnd_cache( printer->info_2->sharename );
+ send_printer_mod_msg( printer->info_2->sharename );
switch (level) {
case 2:
@@ -3529,7 +3586,7 @@ WERROR mod_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
of client's spoolss service in order for the
client's cache to show updates */
- printer.info_2->changeid = rev_changeid();
+ printer->info_2->changeid = rev_changeid();
/*
* Because one day someone will ask:
@@ -3550,7 +3607,7 @@ WERROR mod_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
* 14/12/01 --jerry
*/
- result=update_a_printer_2(printer.info_2);
+ result=update_a_printer_2(printer->info_2);
break;
}
@@ -3758,7 +3815,7 @@ done:
Update (i.e. save) the driver init info (DEVMODE and values) for a printer
****************************************************************************/
-uint32 update_driver_init(NT_PRINTER_INFO_LEVEL printer, uint32 level)
+static uint32 update_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level)
{
uint32 result;
@@ -3766,7 +3823,7 @@ uint32 update_driver_init(NT_PRINTER_INFO_LEVEL printer, uint32 level)
switch (level) {
case 2:
- result = update_driver_init_2(printer.info_2);
+ result = update_driver_init_2(printer->info_2);
break;
default:
result = 1;
@@ -3871,7 +3928,7 @@ static WERROR save_driver_init_2(NT_PRINTER_INFO_LEVEL *printer, uint8 *data, ui
*
*/
- if ( update_driver_init(*printer, 2) != 0 ) {
+ if ( update_driver_init(printer, 2) != 0 ) {
DEBUG(10,("save_driver_init_2: error updating DEVMODE\n"));
status = WERR_NOMEM;
goto done;
@@ -3882,7 +3939,7 @@ static WERROR save_driver_init_2(NT_PRINTER_INFO_LEVEL *printer, uint8 *data, ui
* printer to match it. This allows initialization of the current printer
* as well as the driver.
*/
- status = mod_a_printer(*printer, 2);
+ status = mod_a_printer(printer, 2);
if (!W_ERROR_IS_OK(status)) {
DEBUG(10,("save_driver_init_2: error setting DEVMODE on printer [%s]\n",
printer->info_2->printername));
@@ -4058,7 +4115,7 @@ WERROR get_a_printer( Printer_entry *print_hnd, NT_PRINTER_INFO_LEVEL **pp_print
/* we have a new printer now. Save it with this handle */
if ( W_ERROR_IS_OK(result) ) {
- dump_a_printer(*printer, level);
+ dump_a_printer(printer, level);
/* save a copy in cache */
if ( print_hnd && (print_hnd->printer_type==PRINTER_HANDLE_IS_PRINTER)) {