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"
29 #include "../libcli/registry/util_reg.h"
31 #include "../librpc/ndr/libndr.h"
32 #include "rpc_client/cli_winreg_spoolss.h"
35 /*****************************************************************
36 ****************************************************************/
38 WERROR
nt_printer_guid_store(struct messaging_context
*msg_ctx
,
39 const char *printer
, struct GUID guid
)
42 const struct auth_session_info
*session_info
;
47 tmp_ctx
= talloc_new(NULL
);
49 DEBUG(0, ("Out of memory?!\n"));
50 return WERR_NOT_ENOUGH_MEMORY
;
53 session_info
= get_session_info_system();
54 if (session_info
== NULL
) {
55 DEBUG(0, ("Could not get system session_info\n"));
56 result
= WERR_NOT_ENOUGH_MEMORY
;
60 guid_str
= GUID_string(tmp_ctx
, &guid
);
62 DEBUG(0, ("Out of memory?!\n"));
63 result
= WERR_NOT_ENOUGH_MEMORY
;
67 /* We used to store this as a REG_BINARY but that causes
70 if (!push_reg_sz(tmp_ctx
, &blob
, guid_str
)) {
71 DEBUG(0, ("Could not marshall string %s for objectGUID\n",
73 result
= WERR_NOT_ENOUGH_MEMORY
;
77 result
= winreg_set_printer_dataex_internal(tmp_ctx
, session_info
, msg_ctx
,
79 SPOOL_DSSPOOLER_KEY
, "objectGUID",
80 REG_SZ
, blob
.data
, blob
.length
);
81 if (!W_ERROR_IS_OK(result
)) {
82 DEBUG(0, ("Failed to store GUID for printer %s\n", printer
));
93 static WERROR
nt_printer_dn_lookup(TALLOC_CTX
*mem_ctx
,
98 char *printer_dn
= NULL
;
100 char *srv_cn_0
= NULL
;
101 char *srv_cn_escaped
= NULL
;
102 char *sharename_escaped
= NULL
;
103 char *srv_dn_utf8
= NULL
;
104 char **srv_cn_utf8
= NULL
;
105 size_t converted_size
;
106 ADS_STATUS ads_status
;
111 ads_status
= ads_find_machine_acct(ads
, &res
, lp_netbios_name());
112 if (!ADS_ERR_OK(ads_status
)) {
113 DEBUG(2, ("Failed to find machine account for %s\n",
115 result
= WERR_NOT_FOUND
;
120 * We use ldap_get_dn here as we need the answer in utf8 to call
121 * ldap_explode_dn(). JRA.
123 srv_dn_utf8
= ldap_get_dn((LDAP
*)ads
->ldap
.ld
, (LDAPMessage
*)res
);
124 ads_msgfree(ads
, res
);
125 if (srv_dn_utf8
== NULL
) {
126 result
= WERR_RPC_S_SERVER_UNAVAILABLE
;
130 srv_cn_utf8
= ldap_explode_dn(srv_dn_utf8
, 1);
131 if (srv_cn_utf8
== NULL
) {
132 ldap_memfree(srv_dn_utf8
);
133 result
= WERR_RPC_S_SERVER_UNAVAILABLE
;
137 /* Now convert to CH_UNIX. */
138 ok
= pull_utf8_talloc(mem_ctx
, &srv_dn
, srv_dn_utf8
, &converted_size
);
139 ldap_memfree(srv_dn_utf8
);
141 ldap_memfree(srv_cn_utf8
);
142 result
= WERR_RPC_S_SERVER_UNAVAILABLE
;
146 ok
= pull_utf8_talloc(mem_ctx
, &srv_cn_0
, srv_cn_utf8
[0], &converted_size
);
147 ldap_memfree(srv_cn_utf8
);
149 result
= WERR_RPC_S_SERVER_UNAVAILABLE
;
153 srv_cn_escaped
= escape_rdn_val_string_alloc(srv_cn_0
);
154 if (srv_cn_escaped
== NULL
) {
155 result
= WERR_RPC_S_SERVER_UNAVAILABLE
;
159 sharename_escaped
= escape_rdn_val_string_alloc(printer
);
160 if (sharename_escaped
== NULL
) {
161 result
= WERR_RPC_S_SERVER_UNAVAILABLE
;
165 printer_dn
= talloc_asprintf(mem_ctx
,
170 if (printer_dn
== NULL
) {
171 result
= WERR_NOT_ENOUGH_MEMORY
;
175 *pprinter_dn
= printer_dn
;
179 SAFE_FREE(sharename_escaped
);
180 SAFE_FREE(srv_cn_escaped
);
181 TALLOC_FREE(srv_cn_0
);
186 static WERROR
nt_printer_guid_retrieve_internal(ADS_STRUCT
*ads
,
187 const char *printer_dn
,
190 ADS_STATUS ads_status
;
192 const char *attrs
[] = {"objectGUID", NULL
};
196 ads_status
= ads_search_dn(ads
, &res
, printer_dn
, attrs
);
197 if (!ADS_ERR_OK(ads_status
)) {
198 DEBUG(2, ("Failed to retrieve GUID from DC - %s\n",
199 ads_errstr(ads_status
)));
200 return WERR_FILE_NOT_FOUND
;
204 ok
= ads_pull_guid(ads
, res
, &guid
);
205 ads_msgfree(ads
, res
);
207 return WERR_NOT_ENOUGH_MEMORY
;
215 WERROR
nt_printer_guid_retrieve(TALLOC_CTX
*mem_ctx
, const char *printer
,
218 ADS_STRUCT
*ads
= NULL
;
219 char *old_krb5ccname
= NULL
;
222 ADS_STATUS ads_status
;
223 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
224 char *machine_password
= NULL
;
226 ads
= ads_init(tmp_ctx
,
232 result
= WERR_RPC_S_SERVER_UNAVAILABLE
;
236 old_krb5ccname
= getenv(KRB5_ENV_CCNAME
);
237 setenv(KRB5_ENV_CCNAME
, "MEMORY:prtpub_cache", 1);
238 TALLOC_FREE(ads
->auth
.password
);
239 machine_password
= secrets_fetch_machine_password(lp_workgroup(),
241 if (machine_password
!= NULL
) {
242 ads
->auth
.password
= talloc_strdup(ads
, machine_password
);
243 SAFE_FREE(machine_password
);
244 if (ads
->auth
.password
== NULL
) {
245 result
= WERR_NOT_ENOUGH_MEMORY
;
250 ads_status
= ads_connect(ads
);
251 if (!ADS_ERR_OK(ads_status
)) {
252 DEBUG(3, ("ads_connect failed: %s\n", ads_errstr(ads_status
)));
253 result
= WERR_ACCESS_DENIED
;
257 result
= nt_printer_dn_lookup(tmp_ctx
, ads
, printer
, &printer_dn
);
258 if (!W_ERROR_IS_OK(result
)) {
262 result
= nt_printer_guid_retrieve_internal(ads
, printer_dn
, pguid
);
264 TALLOC_FREE(tmp_ctx
);
265 ads_kdestroy("MEMORY:prtpub_cache");
266 unsetenv(KRB5_ENV_CCNAME
);
267 if (old_krb5ccname
!= NULL
) {
268 setenv(KRB5_ENV_CCNAME
, old_krb5ccname
, 0);
274 WERROR
nt_printer_guid_get(TALLOC_CTX
*mem_ctx
,
275 const struct auth_session_info
*session_info
,
276 struct messaging_context
*msg_ctx
,
277 const char *printer
, struct GUID
*guid
)
280 enum winreg_Type type
;
286 tmp_ctx
= talloc_new(mem_ctx
);
287 if (tmp_ctx
== NULL
) {
288 DEBUG(0, ("out of memory?!\n"));
289 return WERR_NOT_ENOUGH_MEMORY
;
292 result
= winreg_get_printer_dataex_internal(tmp_ctx
, session_info
,
299 if (!W_ERROR_IS_OK(result
)) {
300 DEBUG(0, ("Failed to get GUID for printer %s\n", printer
));
303 blob
.length
= (size_t)len
;
305 /* We used to store the guid as REG_BINARY, then swapped
306 to REG_SZ for Vista compatibility so check for both */
311 const char *guid_str
;
312 ok
= pull_reg_sz(tmp_ctx
, &blob
, &guid_str
);
314 DEBUG(0, ("Failed to unmarshall GUID for printer %s\n",
316 result
= WERR_REGISTRY_CORRUPT
;
319 status
= GUID_from_string(guid_str
, guid
);
320 if (!NT_STATUS_IS_OK(status
)) {
321 DEBUG(0, ("bad GUID for printer %s\n", printer
));
322 result
= ntstatus_to_werror(status
);
328 if (blob
.length
!= sizeof(struct GUID
)) {
329 DEBUG(0, ("bad GUID for printer %s\n", printer
));
330 result
= WERR_REGISTRY_CORRUPT
;
333 memcpy(guid
, blob
.data
, sizeof(struct GUID
));
336 DEBUG(0,("GUID value stored as invalid type (%d)\n", type
));
337 result
= WERR_REGISTRY_CORRUPT
;
344 talloc_free(tmp_ctx
);
348 static WERROR
nt_printer_devmode_to_mods(TALLOC_CTX
*ctx
,
349 struct spoolss_DeviceMode
*devmode
,
356 the device mode fields bits allow us to make an educated guess if a
357 printer feature is supported. For sure a feature must be unsupported if
358 the fields bit is not set. Device Mode Extra Data and FeatureOptionPairs
359 might help to figure out more information here. Common attributes, that
361 SPOOL_REG_PRINTBINNAMES - printBinNames
362 SPOOL_REG_PRINTMAXXEXTENT - printMaxXExtent
363 SPOOL_REG_PRINTMAXYEXTENT - printMaxYExtent
364 SPOOL_REG_PRINTMINXEXTENT - printMinXExtent
365 SPOOL_REG_PRINTMINYEXTENT - printMinYExtent
366 SPOOL_REG_PRINTSTAPLINGSUPPORTED - printStaplingSupported
367 SPOOL_REG_PRINTPAGESPERMINUTE - printPagesPerMinute
368 SPOOL_REG_PRINTRATE - printRate
369 SPOOL_REG_PRINTRATEUNIT - printRateUnit
370 SPOOL_REG_PRINTMEDIAREADY - printMediaReady
371 SPOOL_REG_PRINTMEDIASUPPORTED - printMediaSupported
372 SPOOL_REG_PRINTNUMBERUP - printNumberUp
373 SPOOL_REG_PRINTMAXCOPIES - printMaxCopies
375 if (devmode
->fields
& DEVMODE_COLOR
) {
376 status
= ads_mod_str(ctx
, mods
, SPOOL_REG_PRINTCOLOR
, "TRUE");
378 status
= ads_mod_str(ctx
, mods
, SPOOL_REG_PRINTCOLOR
, "FALSE");
380 if (!ADS_ERR_OK(status
)) {
381 return WERR_NOT_ENOUGH_MEMORY
;
384 if (devmode
->fields
& DEVMODE_DUPLEX
) {
385 status
= ads_mod_str(ctx
, mods
, SPOOL_REG_PRINTDUPLEXSUPPORTED
, "TRUE");
387 status
= ads_mod_str(ctx
, mods
, SPOOL_REG_PRINTDUPLEXSUPPORTED
, "FALSE");
389 if (!ADS_ERR_OK(status
)) {
390 return WERR_NOT_ENOUGH_MEMORY
;
393 if (devmode
->fields
& DEVMODE_COLLATE
) {
394 status
= ads_mod_str(ctx
, mods
, SPOOL_REG_PRINTCOLLATE
, "TRUE");
396 status
= ads_mod_str(ctx
, mods
, SPOOL_REG_PRINTCOLLATE
, "FALSE");
398 if (!ADS_ERR_OK(status
)) {
399 return WERR_NOT_ENOUGH_MEMORY
;
402 /* portrait mode is always supported, LANDSCAPE is optional */
403 status
= ads_mod_str(ctx
, mods
, SPOOL_REG_PRINTORIENTATIONSSUPPORTED
, "PORTRAIT");
404 if (!ADS_ERR_OK(status
)) {
405 return WERR_NOT_ENOUGH_MEMORY
;
407 if (devmode
->fields
& DEVMODE_ORIENTATION
) {
408 status
= ads_mod_str(ctx
, mods
, SPOOL_REG_PRINTORIENTATIONSSUPPORTED
, "LANDSCAPE");
409 if (!ADS_ERR_OK(status
)) {
410 return WERR_NOT_ENOUGH_MEMORY
;
414 /* the driverVersion attribute in AD contains actually specversion */
415 str
= talloc_asprintf(ctx
, "%u", devmode
->specversion
);
417 return WERR_NOT_ENOUGH_MEMORY
;
419 if (strlen(str
) != 0) {
420 status
= ads_mod_str(ctx
, mods
, SPOOL_REG_DRIVERVERSION
, str
);
421 if (!ADS_ERR_OK(status
)) {
422 return WERR_NOT_ENOUGH_MEMORY
;
426 /* devmode->yresolution is a good candidate for printMaxResolutionSupported */
427 str
= talloc_asprintf(ctx
, "%u", devmode
->yresolution
);
429 return WERR_NOT_ENOUGH_MEMORY
;
431 if (strlen(str
) != 0) {
432 status
= ads_mod_str(ctx
, mods
, SPOOL_REG_PRINTMAXRESOLUTIONSUPPORTED
, str
);
433 if (!ADS_ERR_OK(status
)) {
434 return WERR_NOT_ENOUGH_MEMORY
;
443 static WERROR
nt_printer_info_to_mods(TALLOC_CTX
*ctx
,
444 struct spoolss_PrinterInfo2
*info2
,
449 ads_mod_str(ctx
, mods
, SPOOL_REG_PRINTERNAME
, info2
->sharename
);
450 ads_mod_str(ctx
, mods
, SPOOL_REG_PRINTSHARENAME
, info2
->sharename
);
451 ads_mod_str(ctx
, mods
, SPOOL_REG_SHORTSERVERNAME
, lp_netbios_name());
452 ads_mod_str(ctx
, mods
, SPOOL_REG_SERVERNAME
, get_mydnsfullname());
454 info_str
= talloc_asprintf(ctx
, "\\\\%s\\%s",
455 get_mydnsfullname(), info2
->sharename
);
456 if (info_str
== NULL
) {
457 return WERR_NOT_ENOUGH_MEMORY
;
459 ads_mod_str(ctx
, mods
, SPOOL_REG_UNCNAME
, info_str
);
461 info_str
= talloc_asprintf(ctx
, "%d", 4);
462 if (info_str
== NULL
) {
463 return WERR_NOT_ENOUGH_MEMORY
;
465 ads_mod_str(ctx
, mods
, SPOOL_REG_VERSIONNUMBER
, info_str
);
467 /* empty strings in the mods list result in an attrubute error */
468 if (strlen(info2
->drivername
) != 0)
469 ads_mod_str(ctx
, mods
, SPOOL_REG_DRIVERNAME
, info2
->drivername
);
470 if (strlen(info2
->location
) != 0)
471 ads_mod_str(ctx
, mods
, SPOOL_REG_LOCATION
, info2
->location
);
472 if (strlen(info2
->comment
) != 0)
473 ads_mod_str(ctx
, mods
, SPOOL_REG_DESCRIPTION
, info2
->comment
);
474 if (strlen(info2
->portname
) != 0)
475 ads_mod_str(ctx
, mods
, SPOOL_REG_PORTNAME
, info2
->portname
);
476 if (strlen(info2
->sepfile
) != 0)
477 ads_mod_str(ctx
, mods
, SPOOL_REG_PRINTSEPARATORFILE
, info2
->sepfile
);
479 info_str
= talloc_asprintf(ctx
, "%u", info2
->starttime
);
480 if (info_str
== NULL
) {
481 return WERR_NOT_ENOUGH_MEMORY
;
483 ads_mod_str(ctx
, mods
, SPOOL_REG_PRINTSTARTTIME
, info_str
);
485 info_str
= talloc_asprintf(ctx
, "%u", info2
->untiltime
);
486 if (info_str
== NULL
) {
487 return WERR_NOT_ENOUGH_MEMORY
;
489 ads_mod_str(ctx
, mods
, SPOOL_REG_PRINTENDTIME
, info_str
);
491 info_str
= talloc_asprintf(ctx
, "%u", info2
->priority
);
492 if (info_str
== NULL
) {
493 return WERR_NOT_ENOUGH_MEMORY
;
495 ads_mod_str(ctx
, mods
, SPOOL_REG_PRIORITY
, info_str
);
497 if (info2
->attributes
& PRINTER_ATTRIBUTE_KEEPPRINTEDJOBS
) {
498 ads_mod_str(ctx
, mods
, SPOOL_REG_PRINTKEEPPRINTEDJOBS
, "TRUE");
500 ads_mod_str(ctx
, mods
, SPOOL_REG_PRINTKEEPPRINTEDJOBS
, "FALSE");
503 switch (info2
->attributes
& 0x3) {
505 ads_mod_str(ctx
, mods
, SPOOL_REG_PRINTSPOOLING
,
506 SPOOL_REGVAL_PRINTWHILESPOOLING
);
509 ads_mod_str(ctx
, mods
, SPOOL_REG_PRINTSPOOLING
,
510 SPOOL_REGVAL_PRINTAFTERSPOOLED
);
513 ads_mod_str(ctx
, mods
, SPOOL_REG_PRINTSPOOLING
,
514 SPOOL_REGVAL_PRINTDIRECT
);
517 DEBUG(3, ("unsupported printer attributes %x\n",
521 if (info2
->devmode
!= NULL
) {
523 werr
= nt_printer_devmode_to_mods(ctx
, info2
->devmode
, mods
);
524 if (!W_ERROR_IS_OK(werr
)) {
532 static WERROR
nt_printer_publish_ads(struct messaging_context
*msg_ctx
,
534 struct spoolss_PrinterInfo2
*pinfo2
)
537 TALLOC_CTX
*ctx
= talloc_stackframe();
540 WERROR win_rc
= WERR_OK
;
541 const char *printer
= pinfo2
->sharename
;
542 char *printer_dn
= NULL
;
544 /* build the ads mods */
545 DEBUG(5, ("publishing printer %s\n", printer
));
547 win_rc
= nt_printer_dn_lookup(ctx
, ads
, printer
, &printer_dn
);
548 if (!W_ERROR_IS_OK(win_rc
)) {
549 DEBUG(2, ("Failed to create printer dn\n"));
554 mods
= ads_init_mods(ctx
);
558 return WERR_NOT_ENOUGH_MEMORY
;
561 win_rc
= nt_printer_info_to_mods(ctx
, pinfo2
, &mods
);
562 if (!W_ERROR_IS_OK(win_rc
)) {
568 ads_rc
= ads_mod_printer_entry(ads
, printer_dn
, ctx
, &mods
);
569 if (ads_rc
.err
.rc
== LDAP_NO_SUCH_OBJECT
) {
571 for (i
=0; mods
[i
] != 0; i
++)
573 mods
[i
] = (LDAPMod
*)-1;
574 ads_rc
= ads_add_printer_entry(ads
, printer_dn
, ctx
, &mods
);
577 if (!ADS_ERR_OK(ads_rc
)) {
578 DEBUG(3, ("error publishing %s: %s\n",
579 printer
, ads_errstr(ads_rc
)));
580 /* XXX failed to publish, so no guid to retrieve */
583 win_rc
= nt_printer_guid_retrieve_internal(ads
, printer_dn
, &guid
);
584 if (!W_ERROR_IS_OK(win_rc
)) {
589 win_rc
= nt_printer_guid_store(msg_ctx
, printer
, guid
);
590 if (!W_ERROR_IS_OK(win_rc
)) {
591 DEBUG(3, ("failed to store printer %s guid\n",
593 /* not catastrophic, retrieve on next use */
602 static WERROR
nt_printer_unpublish_ads(ADS_STRUCT
*ads
,
606 LDAPMessage
*res
= NULL
;
609 DEBUG(5, ("unpublishing printer %s\n", printer
));
611 /* remove the printer from the directory */
612 ads_rc
= ads_find_printer_on_server(ads
, &res
,
613 printer
, lp_netbios_name());
615 if (ADS_ERR_OK(ads_rc
) && res
&& ads_count_replies(ads
, res
)) {
616 prt_dn
= ads_get_dn(ads
, talloc_tos(), res
);
618 ads_msgfree(ads
, res
);
619 return WERR_NOT_ENOUGH_MEMORY
;
621 ads_rc
= ads_del_dn(ads
, prt_dn
);
626 ads_msgfree(ads
, res
);
631 /****************************************************************************
632 * Publish a printer in the directory
634 * @param mem_ctx memory context
635 * @param session_info session_info to access winreg pipe
636 * @param pinfo2 printer information
637 * @param action publish/unpublish action
638 * @return WERROR indicating status of publishing
639 ***************************************************************************/
641 WERROR
nt_printer_publish(TALLOC_CTX
*mem_ctx
,
642 const struct auth_session_info
*session_info
,
643 struct messaging_context
*msg_ctx
,
644 struct spoolss_PrinterInfo2
*pinfo2
,
647 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
648 uint32_t info2_mask
= SPOOLSS_PRINTER_INFO_ATTRIBUTES
;
649 struct spoolss_SetPrinterInfo2
*sinfo2
;
651 ADS_STRUCT
*ads
= NULL
;
653 char *old_krb5ccname
= NULL
;
654 char *machine_password
= NULL
;
656 sinfo2
= talloc_zero(tmp_ctx
, struct spoolss_SetPrinterInfo2
);
658 win_rc
= WERR_NOT_ENOUGH_MEMORY
;
663 case DSPRINT_PUBLISH
:
665 pinfo2
->attributes
|= PRINTER_ATTRIBUTE_PUBLISHED
;
667 case DSPRINT_UNPUBLISH
:
668 pinfo2
->attributes
&= (~PRINTER_ATTRIBUTE_PUBLISHED
);
671 win_rc
= WERR_NOT_SUPPORTED
;
675 sinfo2
->attributes
= pinfo2
->attributes
;
677 win_rc
= winreg_update_printer_internal(tmp_ctx
, session_info
, msg_ctx
,
678 pinfo2
->sharename
, info2_mask
,
680 if (!W_ERROR_IS_OK(win_rc
)) {
681 DBG_NOTICE("Failed to update data for printer [%s] - %s\n",
689 ads
= ads_init(tmp_ctx
,
695 DEBUG(3, ("ads_init() failed\n"));
696 win_rc
= WERR_RPC_S_SERVER_UNAVAILABLE
;
699 old_krb5ccname
= getenv(KRB5_ENV_CCNAME
);
700 setenv(KRB5_ENV_CCNAME
, "MEMORY:prtpub_cache", 1);
701 TALLOC_FREE(ads
->auth
.password
);
702 machine_password
= secrets_fetch_machine_password(lp_workgroup(),
704 if (machine_password
!= NULL
) {
705 ads
->auth
.password
= talloc_strdup(ads
, machine_password
);
706 SAFE_FREE(machine_password
);
707 if (ads
->auth
.password
== NULL
) {
708 win_rc
= WERR_NOT_ENOUGH_MEMORY
;
713 /* ads_connect() will find the DC for us */
714 ads_rc
= ads_connect(ads
);
715 if (!ADS_ERR_OK(ads_rc
)) {
716 DEBUG(3, ("ads_connect failed: %s\n", ads_errstr(ads_rc
)));
717 win_rc
= WERR_ACCESS_DENIED
;
722 case DSPRINT_PUBLISH
:
724 win_rc
= nt_printer_publish_ads(msg_ctx
, ads
, pinfo2
);
726 case DSPRINT_UNPUBLISH
:
727 win_rc
= nt_printer_unpublish_ads(ads
, pinfo2
->sharename
);
732 ads_kdestroy("MEMORY:prtpub_cache");
733 unsetenv(KRB5_ENV_CCNAME
);
734 if (old_krb5ccname
) {
735 setenv(KRB5_ENV_CCNAME
, old_krb5ccname
, 0);
738 TALLOC_FREE(tmp_ctx
);
743 WERROR
check_published_printers(struct messaging_context
*msg_ctx
)
745 const struct loadparm_substitution
*lp_sub
=
746 loadparm_s3_global_substitution();
748 ADS_STRUCT
*ads
= NULL
;
750 int n_services
= lp_numservices();
751 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
752 struct auth_session_info
*session_info
= NULL
;
753 struct spoolss_PrinterInfo2
*pinfo2
;
756 char *old_krb5ccname
= NULL
;
757 char *machine_password
= NULL
;
759 ads
= ads_init(tmp_ctx
,
765 DEBUG(3, ("ads_init() failed\n"));
766 TALLOC_FREE(tmp_ctx
);
767 return WERR_RPC_S_SERVER_UNAVAILABLE
;
769 old_krb5ccname
= getenv(KRB5_ENV_CCNAME
);
770 setenv(KRB5_ENV_CCNAME
, "MEMORY:prtpub_cache", 1);
771 TALLOC_FREE(ads
->auth
.password
);
772 machine_password
= secrets_fetch_machine_password(lp_workgroup(),
774 if (machine_password
!= NULL
) {
775 ads
->auth
.password
= talloc_strdup(ads
, machine_password
);
776 SAFE_FREE(machine_password
);
777 if (ads
->auth
.password
== NULL
) {
778 result
= WERR_NOT_ENOUGH_MEMORY
;
782 /* ads_connect() will find the DC for us */
783 ads_rc
= ads_connect(ads
);
784 if (!ADS_ERR_OK(ads_rc
)) {
785 DEBUG(3, ("ads_connect failed: %s\n", ads_errstr(ads_rc
)));
786 result
= WERR_ACCESS_DENIED
;
790 status
= make_session_info_system(tmp_ctx
, &session_info
);
791 if (!NT_STATUS_IS_OK(status
)) {
792 DEBUG(0, ("check_published_printers: "
793 "Could not create system session_info\n"));
794 result
= WERR_ACCESS_DENIED
;
798 for (snum
= 0; snum
< n_services
; snum
++) {
799 if (!lp_snum_ok(snum
) || !lp_printable(snum
)) {
803 result
= winreg_get_printer_internal(tmp_ctx
, session_info
, msg_ctx
,
804 lp_servicename(talloc_tos(), lp_sub
, snum
),
806 if (!W_ERROR_IS_OK(result
)) {
810 if (pinfo2
->attributes
& PRINTER_ATTRIBUTE_PUBLISHED
) {
811 nt_printer_publish_ads(msg_ctx
, ads
, pinfo2
);
819 ads_kdestroy("MEMORY:prtpub_cache");
820 unsetenv(KRB5_ENV_CCNAME
);
821 if (old_krb5ccname
) {
822 setenv(KRB5_ENV_CCNAME
, old_krb5ccname
, 0);
824 talloc_free(tmp_ctx
);
828 bool is_printer_published(TALLOC_CTX
*mem_ctx
,
829 const struct auth_session_info
*session_info
,
830 struct messaging_context
*msg_ctx
,
831 const char *servername
,
833 struct spoolss_PrinterInfo2
**info2
)
835 struct spoolss_PrinterInfo2
*pinfo2
= NULL
;
837 struct dcerpc_binding_handle
*b
;
839 result
= winreg_printer_binding_handle(mem_ctx
,
843 if (!W_ERROR_IS_OK(result
)) {
847 result
= winreg_get_printer(mem_ctx
, b
,
849 if (!W_ERROR_IS_OK(result
)) {
853 if (!(pinfo2
->attributes
& PRINTER_ATTRIBUTE_PUBLISHED
)) {
859 *info2
= talloc_move(mem_ctx
, &pinfo2
);
865 WERROR
nt_printer_guid_store(struct messaging_context
*msg_ctx
,
866 const char *printer
, struct GUID guid
)
868 return WERR_NOT_SUPPORTED
;
871 WERROR
nt_printer_guid_retrieve(TALLOC_CTX
*mem_ctx
, const char *printer
,
874 return WERR_NOT_SUPPORTED
;
877 WERROR
nt_printer_guid_get(TALLOC_CTX
*mem_ctx
,
878 const struct auth_session_info
*session_info
,
879 struct messaging_context
*msg_ctx
,
880 const char *printer
, struct GUID
*guid
)
882 return WERR_NOT_SUPPORTED
;
885 WERROR
nt_printer_publish(TALLOC_CTX
*mem_ctx
,
886 const struct auth_session_info
*session_info
,
887 struct messaging_context
*msg_ctx
,
888 struct spoolss_PrinterInfo2
*pinfo2
,
894 WERROR
check_published_printers(struct messaging_context
*msg_ctx
)
899 bool is_printer_published(TALLOC_CTX
*mem_ctx
,
900 const struct auth_session_info
*session_info
,
901 struct messaging_context
*msg_ctx
,
902 const char *servername
,
904 struct spoolss_PrinterInfo2
**info2
)
908 #endif /* HAVE_ADS */