2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Copyright (C) Andrew Tridgell 1992-2000,
5 * Copyright (C) Jean François Micouleau 1998-2000.
6 * Copyright (C) Gerald Carter 2002-2005.
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 3 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, see <http://www.gnu.org/licenses/>.
23 #include "../librpc/gen_ndr/spoolss.h"
24 #include "rpc_server/spoolss/srv_spoolss_util.h"
25 #include "nt_printing.h"
28 #include "../libcli/registry/util_reg.h"
30 #include "../librpc/ndr/libndr.h"
31 #include "rpc_client/cli_winreg_spoolss.h"
34 /*****************************************************************
35 ****************************************************************/
37 WERROR
nt_printer_guid_store(struct messaging_context
*msg_ctx
,
38 const char *printer
, struct GUID guid
)
41 const struct auth_session_info
*session_info
;
46 tmp_ctx
= talloc_new(NULL
);
48 DEBUG(0, ("Out of memory?!\n"));
49 return WERR_NOT_ENOUGH_MEMORY
;
52 session_info
= get_session_info_system();
53 if (session_info
== NULL
) {
54 DEBUG(0, ("Could not get system session_info\n"));
55 result
= WERR_NOT_ENOUGH_MEMORY
;
59 guid_str
= GUID_string(tmp_ctx
, &guid
);
61 DEBUG(0, ("Out of memory?!\n"));
62 result
= WERR_NOT_ENOUGH_MEMORY
;
66 /* We used to store this as a REG_BINARY but that causes
69 if (!push_reg_sz(tmp_ctx
, &blob
, guid_str
)) {
70 DEBUG(0, ("Could not marshall string %s for objectGUID\n",
72 result
= WERR_NOT_ENOUGH_MEMORY
;
76 result
= winreg_set_printer_dataex_internal(tmp_ctx
, session_info
, msg_ctx
,
78 SPOOL_DSSPOOLER_KEY
, "objectGUID",
79 REG_SZ
, blob
.data
, blob
.length
);
80 if (!W_ERROR_IS_OK(result
)) {
81 DEBUG(0, ("Failed to store GUID for printer %s\n", printer
));
92 static WERROR
nt_printer_dn_lookup(TALLOC_CTX
*mem_ctx
,
97 char *printer_dn
= NULL
;
99 char *srv_cn_0
= NULL
;
100 char *srv_cn_escaped
= NULL
;
101 char *sharename_escaped
= NULL
;
102 char *srv_dn_utf8
= NULL
;
103 char **srv_cn_utf8
= NULL
;
104 size_t converted_size
;
105 ADS_STATUS ads_status
;
110 ads_status
= ads_find_machine_acct(ads
, &res
, lp_netbios_name());
111 if (!ADS_ERR_OK(ads_status
)) {
112 DEBUG(2, ("Failed to find machine account for %s\n",
114 result
= WERR_NOT_FOUND
;
119 * We use ldap_get_dn here as we need the answer in utf8 to call
120 * ldap_explode_dn(). JRA.
122 srv_dn_utf8
= ldap_get_dn((LDAP
*)ads
->ldap
.ld
, (LDAPMessage
*)res
);
123 ads_msgfree(ads
, res
);
124 if (srv_dn_utf8
== NULL
) {
125 result
= WERR_RPC_S_SERVER_UNAVAILABLE
;
129 srv_cn_utf8
= ldap_explode_dn(srv_dn_utf8
, 1);
130 if (srv_cn_utf8
== NULL
) {
131 ldap_memfree(srv_dn_utf8
);
132 result
= WERR_RPC_S_SERVER_UNAVAILABLE
;
136 /* Now convert to CH_UNIX. */
137 ok
= pull_utf8_talloc(mem_ctx
, &srv_dn
, srv_dn_utf8
, &converted_size
);
138 ldap_memfree(srv_dn_utf8
);
140 ldap_memfree(srv_cn_utf8
);
141 result
= WERR_RPC_S_SERVER_UNAVAILABLE
;
145 ok
= pull_utf8_talloc(mem_ctx
, &srv_cn_0
, srv_cn_utf8
[0], &converted_size
);
146 ldap_memfree(srv_cn_utf8
);
148 result
= WERR_RPC_S_SERVER_UNAVAILABLE
;
152 srv_cn_escaped
= escape_rdn_val_string_alloc(srv_cn_0
);
153 if (srv_cn_escaped
== NULL
) {
154 result
= WERR_RPC_S_SERVER_UNAVAILABLE
;
158 sharename_escaped
= escape_rdn_val_string_alloc(printer
);
159 if (sharename_escaped
== NULL
) {
160 result
= WERR_RPC_S_SERVER_UNAVAILABLE
;
164 printer_dn
= talloc_asprintf(mem_ctx
,
169 if (printer_dn
== NULL
) {
170 result
= WERR_NOT_ENOUGH_MEMORY
;
174 *pprinter_dn
= printer_dn
;
178 SAFE_FREE(sharename_escaped
);
179 SAFE_FREE(srv_cn_escaped
);
180 TALLOC_FREE(srv_cn_0
);
185 static WERROR
nt_printer_guid_retrieve_internal(ADS_STRUCT
*ads
,
186 const char *printer_dn
,
189 ADS_STATUS ads_status
;
191 const char *attrs
[] = {"objectGUID", NULL
};
195 ads_status
= ads_search_dn(ads
, &res
, printer_dn
, attrs
);
196 if (!ADS_ERR_OK(ads_status
)) {
197 DEBUG(2, ("Failed to retrieve GUID from DC - %s\n",
198 ads_errstr(ads_status
)));
199 return WERR_FILE_NOT_FOUND
;
203 ok
= ads_pull_guid(ads
, res
, &guid
);
204 ads_msgfree(ads
, res
);
206 return WERR_NOT_ENOUGH_MEMORY
;
214 WERROR
nt_printer_guid_retrieve(TALLOC_CTX
*mem_ctx
, const char *printer
,
217 ADS_STRUCT
*ads
= NULL
;
220 ADS_STATUS ads_status
;
221 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
223 ads
= ads_init(tmp_ctx
,
229 result
= WERR_RPC_S_SERVER_UNAVAILABLE
;
233 ads_status
= ads_connect_machine(ads
);
234 if (!ADS_ERR_OK(ads_status
)) {
235 DEBUG(3, ("ads_connect_machine failed: %s\n", ads_errstr(ads_status
)));
236 result
= WERR_ACCESS_DENIED
;
240 result
= nt_printer_dn_lookup(tmp_ctx
, ads
, printer
, &printer_dn
);
241 if (!W_ERROR_IS_OK(result
)) {
245 result
= nt_printer_guid_retrieve_internal(ads
, printer_dn
, pguid
);
247 TALLOC_FREE(tmp_ctx
);
252 WERROR
nt_printer_guid_get(TALLOC_CTX
*mem_ctx
,
253 const struct auth_session_info
*session_info
,
254 struct messaging_context
*msg_ctx
,
255 const char *printer
, struct GUID
*guid
)
258 enum winreg_Type type
;
264 tmp_ctx
= talloc_new(mem_ctx
);
265 if (tmp_ctx
== NULL
) {
266 DEBUG(0, ("out of memory?!\n"));
267 return WERR_NOT_ENOUGH_MEMORY
;
270 result
= winreg_get_printer_dataex_internal(tmp_ctx
, session_info
,
277 if (!W_ERROR_IS_OK(result
)) {
278 DEBUG(0, ("Failed to get GUID for printer %s\n", printer
));
281 blob
.length
= (size_t)len
;
283 /* We used to store the guid as REG_BINARY, then swapped
284 to REG_SZ for Vista compatibility so check for both */
289 const char *guid_str
;
290 ok
= pull_reg_sz(tmp_ctx
, &blob
, &guid_str
);
292 DEBUG(0, ("Failed to unmarshall GUID for printer %s\n",
294 result
= WERR_REGISTRY_CORRUPT
;
297 status
= GUID_from_string(guid_str
, guid
);
298 if (!NT_STATUS_IS_OK(status
)) {
299 DEBUG(0, ("bad GUID for printer %s\n", printer
));
300 result
= ntstatus_to_werror(status
);
306 if (blob
.length
!= sizeof(struct GUID
)) {
307 DEBUG(0, ("bad GUID for printer %s\n", printer
));
308 result
= WERR_REGISTRY_CORRUPT
;
311 memcpy(guid
, blob
.data
, sizeof(struct GUID
));
314 DEBUG(0,("GUID value stored as invalid type (%d)\n", type
));
315 result
= WERR_REGISTRY_CORRUPT
;
322 talloc_free(tmp_ctx
);
326 static WERROR
nt_printer_devmode_to_mods(TALLOC_CTX
*ctx
,
327 struct spoolss_DeviceMode
*devmode
,
334 the device mode fields bits allow us to make an educated guess if a
335 printer feature is supported. For sure a feature must be unsupported if
336 the fields bit is not set. Device Mode Extra Data and FeatureOptionPairs
337 might help to figure out more information here. Common attributes, that
339 SPOOL_REG_PRINTBINNAMES - printBinNames
340 SPOOL_REG_PRINTMAXXEXTENT - printMaxXExtent
341 SPOOL_REG_PRINTMAXYEXTENT - printMaxYExtent
342 SPOOL_REG_PRINTMINXEXTENT - printMinXExtent
343 SPOOL_REG_PRINTMINYEXTENT - printMinYExtent
344 SPOOL_REG_PRINTSTAPLINGSUPPORTED - printStaplingSupported
345 SPOOL_REG_PRINTPAGESPERMINUTE - printPagesPerMinute
346 SPOOL_REG_PRINTRATE - printRate
347 SPOOL_REG_PRINTRATEUNIT - printRateUnit
348 SPOOL_REG_PRINTMEDIAREADY - printMediaReady
349 SPOOL_REG_PRINTMEDIASUPPORTED - printMediaSupported
350 SPOOL_REG_PRINTNUMBERUP - printNumberUp
351 SPOOL_REG_PRINTMAXCOPIES - printMaxCopies
353 if (devmode
->fields
& DEVMODE_COLOR
) {
354 status
= ads_mod_str(ctx
, mods
, SPOOL_REG_PRINTCOLOR
, "TRUE");
356 status
= ads_mod_str(ctx
, mods
, SPOOL_REG_PRINTCOLOR
, "FALSE");
358 if (!ADS_ERR_OK(status
)) {
359 return WERR_NOT_ENOUGH_MEMORY
;
362 if (devmode
->fields
& DEVMODE_DUPLEX
) {
363 status
= ads_mod_str(ctx
, mods
, SPOOL_REG_PRINTDUPLEXSUPPORTED
, "TRUE");
365 status
= ads_mod_str(ctx
, mods
, SPOOL_REG_PRINTDUPLEXSUPPORTED
, "FALSE");
367 if (!ADS_ERR_OK(status
)) {
368 return WERR_NOT_ENOUGH_MEMORY
;
371 if (devmode
->fields
& DEVMODE_COLLATE
) {
372 status
= ads_mod_str(ctx
, mods
, SPOOL_REG_PRINTCOLLATE
, "TRUE");
374 status
= ads_mod_str(ctx
, mods
, SPOOL_REG_PRINTCOLLATE
, "FALSE");
376 if (!ADS_ERR_OK(status
)) {
377 return WERR_NOT_ENOUGH_MEMORY
;
380 /* portrait mode is always supported, LANDSCAPE is optional */
381 status
= ads_mod_str(ctx
, mods
, SPOOL_REG_PRINTORIENTATIONSSUPPORTED
, "PORTRAIT");
382 if (!ADS_ERR_OK(status
)) {
383 return WERR_NOT_ENOUGH_MEMORY
;
385 if (devmode
->fields
& DEVMODE_ORIENTATION
) {
386 status
= ads_mod_str(ctx
, mods
, SPOOL_REG_PRINTORIENTATIONSSUPPORTED
, "LANDSCAPE");
387 if (!ADS_ERR_OK(status
)) {
388 return WERR_NOT_ENOUGH_MEMORY
;
392 /* the driverVersion attribute in AD contains actually specversion */
393 str
= talloc_asprintf(ctx
, "%u", devmode
->specversion
);
395 return WERR_NOT_ENOUGH_MEMORY
;
397 if (strlen(str
) != 0) {
398 status
= ads_mod_str(ctx
, mods
, SPOOL_REG_DRIVERVERSION
, str
);
399 if (!ADS_ERR_OK(status
)) {
400 return WERR_NOT_ENOUGH_MEMORY
;
404 /* devmode->yresolution is a good candidate for printMaxResolutionSupported */
405 str
= talloc_asprintf(ctx
, "%u", devmode
->yresolution
);
407 return WERR_NOT_ENOUGH_MEMORY
;
409 if (strlen(str
) != 0) {
410 status
= ads_mod_str(ctx
, mods
, SPOOL_REG_PRINTMAXRESOLUTIONSUPPORTED
, str
);
411 if (!ADS_ERR_OK(status
)) {
412 return WERR_NOT_ENOUGH_MEMORY
;
421 static WERROR
nt_printer_info_to_mods(TALLOC_CTX
*ctx
,
422 struct spoolss_PrinterInfo2
*info2
,
427 ads_mod_str(ctx
, mods
, SPOOL_REG_PRINTERNAME
, info2
->sharename
);
428 ads_mod_str(ctx
, mods
, SPOOL_REG_PRINTSHARENAME
, info2
->sharename
);
429 ads_mod_str(ctx
, mods
, SPOOL_REG_SHORTSERVERNAME
, lp_netbios_name());
430 ads_mod_str(ctx
, mods
, SPOOL_REG_SERVERNAME
, get_mydnsfullname());
432 info_str
= talloc_asprintf(ctx
, "\\\\%s\\%s",
433 get_mydnsfullname(), info2
->sharename
);
434 if (info_str
== NULL
) {
435 return WERR_NOT_ENOUGH_MEMORY
;
437 ads_mod_str(ctx
, mods
, SPOOL_REG_UNCNAME
, info_str
);
439 info_str
= talloc_asprintf(ctx
, "%d", 4);
440 if (info_str
== NULL
) {
441 return WERR_NOT_ENOUGH_MEMORY
;
443 ads_mod_str(ctx
, mods
, SPOOL_REG_VERSIONNUMBER
, info_str
);
445 /* empty strings in the mods list result in an attribute error */
446 if (strlen(info2
->drivername
) != 0)
447 ads_mod_str(ctx
, mods
, SPOOL_REG_DRIVERNAME
, info2
->drivername
);
448 if (strlen(info2
->location
) != 0)
449 ads_mod_str(ctx
, mods
, SPOOL_REG_LOCATION
, info2
->location
);
450 if (strlen(info2
->comment
) != 0)
451 ads_mod_str(ctx
, mods
, SPOOL_REG_DESCRIPTION
, info2
->comment
);
452 if (strlen(info2
->portname
) != 0)
453 ads_mod_str(ctx
, mods
, SPOOL_REG_PORTNAME
, info2
->portname
);
454 if (strlen(info2
->sepfile
) != 0)
455 ads_mod_str(ctx
, mods
, SPOOL_REG_PRINTSEPARATORFILE
, info2
->sepfile
);
457 info_str
= talloc_asprintf(ctx
, "%u", info2
->starttime
);
458 if (info_str
== NULL
) {
459 return WERR_NOT_ENOUGH_MEMORY
;
461 ads_mod_str(ctx
, mods
, SPOOL_REG_PRINTSTARTTIME
, info_str
);
463 info_str
= talloc_asprintf(ctx
, "%u", info2
->untiltime
);
464 if (info_str
== NULL
) {
465 return WERR_NOT_ENOUGH_MEMORY
;
467 ads_mod_str(ctx
, mods
, SPOOL_REG_PRINTENDTIME
, info_str
);
469 info_str
= talloc_asprintf(ctx
, "%u", info2
->priority
);
470 if (info_str
== NULL
) {
471 return WERR_NOT_ENOUGH_MEMORY
;
473 ads_mod_str(ctx
, mods
, SPOOL_REG_PRIORITY
, info_str
);
475 if (info2
->attributes
& PRINTER_ATTRIBUTE_KEEPPRINTEDJOBS
) {
476 ads_mod_str(ctx
, mods
, SPOOL_REG_PRINTKEEPPRINTEDJOBS
, "TRUE");
478 ads_mod_str(ctx
, mods
, SPOOL_REG_PRINTKEEPPRINTEDJOBS
, "FALSE");
481 switch (info2
->attributes
& 0x3) {
483 ads_mod_str(ctx
, mods
, SPOOL_REG_PRINTSPOOLING
,
484 SPOOL_REGVAL_PRINTWHILESPOOLING
);
487 ads_mod_str(ctx
, mods
, SPOOL_REG_PRINTSPOOLING
,
488 SPOOL_REGVAL_PRINTAFTERSPOOLED
);
491 ads_mod_str(ctx
, mods
, SPOOL_REG_PRINTSPOOLING
,
492 SPOOL_REGVAL_PRINTDIRECT
);
495 DEBUG(3, ("unsupported printer attributes %x\n",
499 if (info2
->devmode
!= NULL
) {
501 werr
= nt_printer_devmode_to_mods(ctx
, info2
->devmode
, mods
);
502 if (!W_ERROR_IS_OK(werr
)) {
510 static WERROR
nt_printer_publish_ads(struct messaging_context
*msg_ctx
,
512 struct spoolss_PrinterInfo2
*pinfo2
)
515 TALLOC_CTX
*ctx
= talloc_stackframe();
518 WERROR win_rc
= WERR_OK
;
519 const char *printer
= pinfo2
->sharename
;
520 char *printer_dn
= NULL
;
522 /* build the ads mods */
523 DEBUG(5, ("publishing printer %s\n", printer
));
525 win_rc
= nt_printer_dn_lookup(ctx
, ads
, printer
, &printer_dn
);
526 if (!W_ERROR_IS_OK(win_rc
)) {
527 DEBUG(2, ("Failed to create printer dn\n"));
532 mods
= ads_init_mods(ctx
);
536 return WERR_NOT_ENOUGH_MEMORY
;
539 win_rc
= nt_printer_info_to_mods(ctx
, pinfo2
, &mods
);
540 if (!W_ERROR_IS_OK(win_rc
)) {
546 ads_rc
= ads_mod_printer_entry(ads
, printer_dn
, ctx
, &mods
);
547 if (ads_rc
.err
.rc
== LDAP_NO_SUCH_OBJECT
) {
549 for (i
=0; mods
[i
] != 0; i
++)
551 mods
[i
] = (LDAPMod
*)-1;
552 ads_rc
= ads_add_printer_entry(ads
, printer_dn
, ctx
, &mods
);
555 if (!ADS_ERR_OK(ads_rc
)) {
556 DEBUG(3, ("error publishing %s: %s\n",
557 printer
, ads_errstr(ads_rc
)));
558 /* XXX failed to publish, so no guid to retrieve */
561 win_rc
= nt_printer_guid_retrieve_internal(ads
, printer_dn
, &guid
);
562 if (!W_ERROR_IS_OK(win_rc
)) {
567 win_rc
= nt_printer_guid_store(msg_ctx
, printer
, guid
);
568 if (!W_ERROR_IS_OK(win_rc
)) {
569 DEBUG(3, ("failed to store printer %s guid\n",
571 /* not catastrophic, retrieve on next use */
580 static WERROR
nt_printer_unpublish_ads(ADS_STRUCT
*ads
,
584 LDAPMessage
*res
= NULL
;
587 DEBUG(5, ("unpublishing printer %s\n", printer
));
589 /* remove the printer from the directory */
590 ads_rc
= ads_find_printer_on_server(ads
, &res
,
591 printer
, lp_netbios_name());
593 if (ADS_ERR_OK(ads_rc
) && res
&& ads_count_replies(ads
, res
)) {
594 prt_dn
= ads_get_dn(ads
, talloc_tos(), res
);
596 ads_msgfree(ads
, res
);
597 return WERR_NOT_ENOUGH_MEMORY
;
599 ads_rc
= ads_del_dn(ads
, prt_dn
);
604 ads_msgfree(ads
, res
);
609 /****************************************************************************
610 * Publish a printer in the directory
612 * @param mem_ctx memory context
613 * @param session_info session_info to access winreg pipe
614 * @param pinfo2 printer information
615 * @param action publish/unpublish action
616 * @return WERROR indicating status of publishing
617 ***************************************************************************/
619 WERROR
nt_printer_publish(TALLOC_CTX
*mem_ctx
,
620 const struct auth_session_info
*session_info
,
621 struct messaging_context
*msg_ctx
,
622 struct spoolss_PrinterInfo2
*pinfo2
,
625 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
626 uint32_t info2_mask
= SPOOLSS_PRINTER_INFO_ATTRIBUTES
;
627 struct spoolss_SetPrinterInfo2
*sinfo2
;
629 ADS_STRUCT
*ads
= NULL
;
632 sinfo2
= talloc_zero(tmp_ctx
, struct spoolss_SetPrinterInfo2
);
634 win_rc
= WERR_NOT_ENOUGH_MEMORY
;
639 case DSPRINT_PUBLISH
:
641 pinfo2
->attributes
|= PRINTER_ATTRIBUTE_PUBLISHED
;
643 case DSPRINT_UNPUBLISH
:
644 pinfo2
->attributes
&= (~PRINTER_ATTRIBUTE_PUBLISHED
);
647 win_rc
= WERR_NOT_SUPPORTED
;
651 sinfo2
->attributes
= pinfo2
->attributes
;
653 win_rc
= winreg_update_printer_internal(tmp_ctx
, session_info
, msg_ctx
,
654 pinfo2
->sharename
, info2_mask
,
656 if (!W_ERROR_IS_OK(win_rc
)) {
657 DBG_NOTICE("Failed to update data for printer [%s] - %s\n",
665 ads
= ads_init(tmp_ctx
,
671 DEBUG(3, ("ads_init() failed\n"));
672 win_rc
= WERR_RPC_S_SERVER_UNAVAILABLE
;
676 /* ads_connect_machine() will find the DC for us */
677 ads_rc
= ads_connect_machine(ads
);
678 if (!ADS_ERR_OK(ads_rc
)) {
679 DEBUG(3, ("ads_connect_machine failed: %s\n", ads_errstr(ads_rc
)));
680 win_rc
= WERR_ACCESS_DENIED
;
685 case DSPRINT_PUBLISH
:
687 win_rc
= nt_printer_publish_ads(msg_ctx
, ads
, pinfo2
);
689 case DSPRINT_UNPUBLISH
:
690 win_rc
= nt_printer_unpublish_ads(ads
, pinfo2
->sharename
);
695 TALLOC_FREE(tmp_ctx
);
700 WERROR
check_published_printers(struct messaging_context
*msg_ctx
)
702 const struct loadparm_substitution
*lp_sub
=
703 loadparm_s3_global_substitution();
705 ADS_STRUCT
*ads
= NULL
;
707 int n_services
= lp_numservices();
708 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
709 struct auth_session_info
*session_info
= NULL
;
710 struct spoolss_PrinterInfo2
*pinfo2
;
714 ads
= ads_init(tmp_ctx
,
720 DEBUG(3, ("ads_init() failed\n"));
721 TALLOC_FREE(tmp_ctx
);
722 return WERR_RPC_S_SERVER_UNAVAILABLE
;
725 /* ads_connect_machine() will find the DC for us */
726 ads_rc
= ads_connect_machine(ads
);
727 if (!ADS_ERR_OK(ads_rc
)) {
728 DEBUG(3, ("ads_connect_machine failed: %s\n", ads_errstr(ads_rc
)));
729 result
= WERR_ACCESS_DENIED
;
733 status
= make_session_info_system(tmp_ctx
, &session_info
);
734 if (!NT_STATUS_IS_OK(status
)) {
735 DEBUG(0, ("check_published_printers: "
736 "Could not create system session_info\n"));
737 result
= WERR_ACCESS_DENIED
;
741 for (snum
= 0; snum
< n_services
; snum
++) {
742 if (!lp_snum_ok(snum
) || !lp_printable(snum
)) {
746 result
= winreg_get_printer_internal(tmp_ctx
, session_info
, msg_ctx
,
747 lp_servicename(talloc_tos(), lp_sub
, snum
),
749 if (!W_ERROR_IS_OK(result
)) {
753 if (pinfo2
->attributes
& PRINTER_ATTRIBUTE_PUBLISHED
) {
754 nt_printer_publish_ads(msg_ctx
, ads
, pinfo2
);
762 talloc_free(tmp_ctx
);
766 bool is_printer_published(TALLOC_CTX
*mem_ctx
,
767 const struct auth_session_info
*session_info
,
768 struct messaging_context
*msg_ctx
,
769 const char *servername
,
771 struct spoolss_PrinterInfo2
**info2
)
773 struct spoolss_PrinterInfo2
*pinfo2
= NULL
;
775 struct dcerpc_binding_handle
*b
;
777 result
= winreg_printer_binding_handle(mem_ctx
,
781 if (!W_ERROR_IS_OK(result
)) {
785 result
= winreg_get_printer(mem_ctx
, b
,
787 if (!W_ERROR_IS_OK(result
)) {
791 if (!(pinfo2
->attributes
& PRINTER_ATTRIBUTE_PUBLISHED
)) {
797 *info2
= talloc_move(mem_ctx
, &pinfo2
);
803 WERROR
nt_printer_guid_store(struct messaging_context
*msg_ctx
,
804 const char *printer
, struct GUID guid
)
806 return WERR_NOT_SUPPORTED
;
809 WERROR
nt_printer_guid_retrieve(TALLOC_CTX
*mem_ctx
, const char *printer
,
812 return WERR_NOT_SUPPORTED
;
815 WERROR
nt_printer_guid_get(TALLOC_CTX
*mem_ctx
,
816 const struct auth_session_info
*session_info
,
817 struct messaging_context
*msg_ctx
,
818 const char *printer
, struct GUID
*guid
)
820 return WERR_NOT_SUPPORTED
;
823 WERROR
nt_printer_publish(TALLOC_CTX
*mem_ctx
,
824 const struct auth_session_info
*session_info
,
825 struct messaging_context
*msg_ctx
,
826 struct spoolss_PrinterInfo2
*pinfo2
,
832 WERROR
check_published_printers(struct messaging_context
*msg_ctx
)
837 bool is_printer_published(TALLOC_CTX
*mem_ctx
,
838 const struct auth_session_info
*session_info
,
839 struct messaging_context
*msg_ctx
,
840 const char *servername
,
842 struct spoolss_PrinterInfo2
**info2
)
846 #endif /* HAVE_ADS */