printing: add nt_printer_guid_retrieve() helper
[Samba.git] / source3 / printing / nt_printing_ads.c
blob6f14e2d400ee671608c1636a5e2c62a76a39283c
1 /*
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/>.
22 #include "includes.h"
23 #include "../librpc/gen_ndr/spoolss.h"
24 #include "rpc_server/spoolss/srv_spoolss_util.h"
25 #include "nt_printing.h"
26 #include "ads.h"
27 #include "secrets.h"
28 #include "krb5_env.h"
29 #include "../libcli/registry/util_reg.h"
30 #include "auth.h"
31 #include "../librpc/ndr/libndr.h"
32 #include "rpc_client/cli_winreg_spoolss.h"
34 #ifdef HAVE_ADS
35 /*****************************************************************
36 ****************************************************************/
38 static void store_printer_guid(struct messaging_context *msg_ctx,
39 const char *printer, struct GUID guid)
41 TALLOC_CTX *tmp_ctx;
42 struct auth_session_info *session_info = NULL;
43 const char *guid_str;
44 DATA_BLOB blob;
45 NTSTATUS status;
46 WERROR result;
48 tmp_ctx = talloc_new(NULL);
49 if (!tmp_ctx) {
50 DEBUG(0, ("store_printer_guid: Out of memory?!\n"));
51 return;
54 status = make_session_info_system(tmp_ctx, &session_info);
55 if (!NT_STATUS_IS_OK(status)) {
56 DEBUG(0, ("store_printer_guid: "
57 "Could not create system session_info\n"));
58 goto done;
61 guid_str = GUID_string(tmp_ctx, &guid);
62 if (!guid_str) {
63 DEBUG(0, ("store_printer_guid: Out of memory?!\n"));
64 goto done;
67 /* We used to store this as a REG_BINARY but that causes
68 Vista to whine */
70 if (!push_reg_sz(tmp_ctx, &blob, guid_str)) {
71 DEBUG(0, ("store_printer_guid: "
72 "Could not marshall string %s for objectGUID\n",
73 guid_str));
74 goto done;
77 result = winreg_set_printer_dataex_internal(tmp_ctx, session_info, msg_ctx,
78 printer,
79 SPOOL_DSSPOOLER_KEY, "objectGUID",
80 REG_SZ, blob.data, blob.length);
81 if (!W_ERROR_IS_OK(result)) {
82 DEBUG(0, ("store_printer_guid: "
83 "Failed to store GUID for printer %s\n", printer));
86 done:
87 talloc_free(tmp_ctx);
90 static WERROR nt_printer_dn_lookup(TALLOC_CTX *mem_ctx,
91 ADS_STRUCT *ads,
92 const char *printer,
93 char **pprinter_dn)
95 char *printer_dn = NULL;
96 char *srv_dn = NULL;
97 char *srv_cn_0 = NULL;
98 char *srv_cn_escaped = NULL;
99 char *sharename_escaped = NULL;
100 char *srv_dn_utf8 = NULL;
101 char **srv_cn_utf8 = NULL;
102 size_t converted_size;
103 ADS_STATUS ads_status;
104 LDAPMessage *res;
105 WERROR result;
106 bool ok;
108 ads_status = ads_find_machine_acct(ads, &res, lp_netbios_name());
109 if (!ADS_ERR_OK(ads_status)) {
110 DEBUG(2, ("Failed to find machine account for %s\n",
111 lp_netbios_name()));
112 result = WERR_NOT_FOUND;
113 goto err_out;
117 * We use ldap_get_dn here as we need the answer in utf8 to call
118 * ldap_explode_dn(). JRA.
120 srv_dn_utf8 = ldap_get_dn((LDAP *)ads->ldap.ld, (LDAPMessage *)res);
121 ads_msgfree(ads, res);
122 if (srv_dn_utf8 == NULL) {
123 result = WERR_SERVER_UNAVAILABLE;
124 goto err_out;
127 srv_cn_utf8 = ldap_explode_dn(srv_dn_utf8, 1);
128 if (srv_cn_utf8 == NULL) {
129 ldap_memfree(srv_dn_utf8);
130 result = WERR_SERVER_UNAVAILABLE;
131 goto err_out;
134 /* Now convert to CH_UNIX. */
135 ok = pull_utf8_talloc(mem_ctx, &srv_dn, srv_dn_utf8, &converted_size);
136 ldap_memfree(srv_dn_utf8);
137 if (!ok) {
138 ldap_memfree(srv_cn_utf8);
139 result = WERR_SERVER_UNAVAILABLE;
140 goto err_out;
143 ok = pull_utf8_talloc(mem_ctx, &srv_cn_0, srv_cn_utf8[0], &converted_size);
144 ldap_memfree(srv_cn_utf8);
145 if (!ok) {
146 result = WERR_SERVER_UNAVAILABLE;
147 goto err_out;
150 srv_cn_escaped = escape_rdn_val_string_alloc(srv_cn_0);
151 if (srv_cn_escaped == NULL) {
152 result = WERR_SERVER_UNAVAILABLE;
153 goto err_out;
156 sharename_escaped = escape_rdn_val_string_alloc(printer);
157 if (sharename_escaped == NULL) {
158 result = WERR_SERVER_UNAVAILABLE;
159 goto err_out;
162 printer_dn = talloc_asprintf(mem_ctx,
163 "cn=%s-%s,%s",
164 srv_cn_escaped,
165 sharename_escaped,
166 srv_dn);
167 if (printer_dn == NULL) {
168 result = WERR_NOMEM;
169 goto err_out;
172 *pprinter_dn = printer_dn;
174 result = WERR_OK;
175 err_out:
176 SAFE_FREE(sharename_escaped);
177 SAFE_FREE(srv_cn_escaped);
178 TALLOC_FREE(srv_cn_0);
179 TALLOC_FREE(srv_dn);
180 return result;
183 static WERROR nt_printer_guid_retrieve_internal(ADS_STRUCT *ads,
184 const char *printer_dn,
185 struct GUID *pguid)
187 ADS_STATUS ads_status;
188 LDAPMessage *res;
189 const char *attrs[] = {"objectGUID", NULL};
190 struct GUID guid;
191 bool ok;
193 ads_status = ads_search_dn(ads, &res, printer_dn, attrs);
194 if (!ADS_ERR_OK(ads_status)) {
195 DEBUG(2, ("Failed to retrieve GUID from DC - %s\n",
196 ads_errstr(ads_status)));
197 return WERR_BADFILE;
200 ZERO_STRUCT(guid);
201 ok = ads_pull_guid(ads, res, &guid);
202 ads_msgfree(ads, res);
203 if (!ok) {
204 return WERR_NOMEM;
207 *pguid = guid;
209 return WERR_OK;
212 WERROR nt_printer_guid_retrieve(TALLOC_CTX *mem_ctx, const char *printer,
213 struct GUID *pguid)
215 ADS_STRUCT *ads = NULL;
216 char *old_krb5ccname = NULL;
217 char *printer_dn;
218 WERROR result;
219 ADS_STATUS ads_status;
220 TALLOC_CTX *tmp_ctx;
222 tmp_ctx = talloc_new(mem_ctx);
223 if (tmp_ctx == NULL) {
224 return WERR_NOMEM;
227 ads = ads_init(lp_realm(), lp_workgroup(), NULL);
228 if (ads == NULL) {
229 result = WERR_SERVER_UNAVAILABLE;
230 goto out;
233 old_krb5ccname = getenv(KRB5_ENV_CCNAME);
234 setenv(KRB5_ENV_CCNAME, "MEMORY:prtpub_cache", 1);
235 SAFE_FREE(ads->auth.password);
236 ads->auth.password = secrets_fetch_machine_password(lp_workgroup(),
237 NULL, NULL);
239 ads_status = ads_connect(ads);
240 if (!ADS_ERR_OK(ads_status)) {
241 DEBUG(3, ("ads_connect failed: %s\n", ads_errstr(ads_status)));
242 result = WERR_ACCESS_DENIED;
243 goto out;
246 result = nt_printer_dn_lookup(tmp_ctx, ads, printer, &printer_dn);
247 if (!W_ERROR_IS_OK(result)) {
248 goto out;
251 result = nt_printer_guid_retrieve_internal(ads, printer_dn, pguid);
252 out:
253 TALLOC_FREE(tmp_ctx);
254 ads_destroy(&ads);
255 ads_kdestroy("MEMORY:prtpub_cache");
256 unsetenv(KRB5_ENV_CCNAME);
257 if (old_krb5ccname != NULL) {
258 setenv(KRB5_ENV_CCNAME, old_krb5ccname, 0);
261 return result;
264 WERROR nt_printer_guid_get(TALLOC_CTX *mem_ctx,
265 const struct auth_session_info *session_info,
266 struct messaging_context *msg_ctx,
267 const char *printer, struct GUID *guid)
269 TALLOC_CTX *tmp_ctx;
270 enum winreg_Type type;
271 DATA_BLOB blob;
272 uint32_t len;
273 NTSTATUS status;
274 WERROR result;
276 tmp_ctx = talloc_new(mem_ctx);
277 if (tmp_ctx == NULL) {
278 DEBUG(0, ("out of memory?!\n"));
279 return WERR_NOMEM;
282 result = winreg_get_printer_dataex_internal(tmp_ctx, session_info,
283 msg_ctx, printer,
284 SPOOL_DSSPOOLER_KEY,
285 "objectGUID",
286 &type,
287 &blob.data,
288 &len);
289 if (!W_ERROR_IS_OK(result)) {
290 DEBUG(0, ("Failed to get GUID for printer %s\n", printer));
291 goto out_ctx_free;
293 blob.length = (size_t)len;
295 /* We used to store the guid as REG_BINARY, then swapped
296 to REG_SZ for Vista compatibility so check for both */
298 switch (type) {
299 case REG_SZ: {
300 bool ok;
301 const char *guid_str;
302 ok = pull_reg_sz(tmp_ctx, &blob, &guid_str);
303 if (!ok) {
304 DEBUG(0, ("Failed to unmarshall GUID for printer %s\n",
305 printer));
306 result = WERR_REG_CORRUPT;
307 goto out_ctx_free;
309 status = GUID_from_string(guid_str, guid);
310 if (!NT_STATUS_IS_OK(status)) {
311 DEBUG(0, ("bad GUID for printer %s\n", printer));
312 result = ntstatus_to_werror(status);
313 goto out_ctx_free;
315 break;
317 case REG_BINARY:
318 if (blob.length != sizeof(struct GUID)) {
319 DEBUG(0, ("bad GUID for printer %s\n", printer));
320 result = WERR_REG_CORRUPT;
321 goto out_ctx_free;
323 memcpy(guid, blob.data, sizeof(struct GUID));
324 break;
325 default:
326 DEBUG(0,("GUID value stored as invalid type (%d)\n", type));
327 result = WERR_REG_CORRUPT;
328 goto out_ctx_free;
329 break;
331 result = WERR_OK;
333 out_ctx_free:
334 talloc_free(tmp_ctx);
335 return result;
338 static WERROR nt_printer_info_to_mods(TALLOC_CTX *ctx,
339 struct spoolss_PrinterInfo2 *info2,
340 ADS_MODLIST *mods)
342 char *info_str;
344 ads_mod_str(ctx, mods, SPOOL_REG_PRINTERNAME, info2->sharename);
345 ads_mod_str(ctx, mods, SPOOL_REG_SHORTSERVERNAME, lp_netbios_name());
346 ads_mod_str(ctx, mods, SPOOL_REG_SERVERNAME, get_mydnsfullname());
348 info_str = talloc_asprintf(ctx, "\\\\%s\\%s",
349 get_mydnsfullname(), info2->sharename);
350 if (info_str == NULL) {
351 return WERR_NOMEM;
353 ads_mod_str(ctx, mods, SPOOL_REG_UNCNAME, info_str);
355 info_str = talloc_asprintf(ctx, "%d", 4);
356 if (info_str == NULL) {
357 return WERR_NOMEM;
359 ads_mod_str(ctx, mods, SPOOL_REG_VERSIONNUMBER, info_str);
361 /* empty strings in the mods list result in an attrubute error */
362 if (strlen(info2->drivername) != 0)
363 ads_mod_str(ctx, mods, SPOOL_REG_DRIVERNAME, info2->drivername);
364 if (strlen(info2->location) != 0)
365 ads_mod_str(ctx, mods, SPOOL_REG_LOCATION, info2->location);
366 if (strlen(info2->comment) != 0)
367 ads_mod_str(ctx, mods, SPOOL_REG_DESCRIPTION, info2->comment);
368 if (strlen(info2->portname) != 0)
369 ads_mod_str(ctx, mods, SPOOL_REG_PORTNAME, info2->portname);
370 if (strlen(info2->sepfile) != 0)
371 ads_mod_str(ctx, mods, SPOOL_REG_PRINTSEPARATORFILE, info2->sepfile);
373 info_str = talloc_asprintf(ctx, "%u", info2->starttime);
374 if (info_str == NULL) {
375 return WERR_NOMEM;
377 ads_mod_str(ctx, mods, SPOOL_REG_PRINTSTARTTIME, info_str);
379 info_str = talloc_asprintf(ctx, "%u", info2->untiltime);
380 if (info_str == NULL) {
381 return WERR_NOMEM;
383 ads_mod_str(ctx, mods, SPOOL_REG_PRINTENDTIME, info_str);
385 info_str = talloc_asprintf(ctx, "%u", info2->priority);
386 if (info_str == NULL) {
387 return WERR_NOMEM;
389 ads_mod_str(ctx, mods, SPOOL_REG_PRIORITY, info_str);
391 if (info2->attributes & PRINTER_ATTRIBUTE_KEEPPRINTEDJOBS) {
392 ads_mod_str(ctx, mods, SPOOL_REG_PRINTKEEPPRINTEDJOBS, "TRUE");
393 } else {
394 ads_mod_str(ctx, mods, SPOOL_REG_PRINTKEEPPRINTEDJOBS, "FALSE");
397 switch (info2->attributes & 0x3) {
398 case 0:
399 ads_mod_str(ctx, mods, SPOOL_REG_PRINTSPOOLING,
400 SPOOL_REGVAL_PRINTWHILESPOOLING);
401 break;
402 case 1:
403 ads_mod_str(ctx, mods, SPOOL_REG_PRINTSPOOLING,
404 SPOOL_REGVAL_PRINTAFTERSPOOLED);
405 break;
406 case 2:
407 ads_mod_str(ctx, mods, SPOOL_REG_PRINTSPOOLING,
408 SPOOL_REGVAL_PRINTDIRECT);
409 break;
410 default:
411 DEBUG(3, ("unsupported printer attributes %x\n",
412 info2->attributes));
415 return WERR_OK;
418 static WERROR nt_printer_publish_ads(struct messaging_context *msg_ctx,
419 ADS_STRUCT *ads,
420 struct spoolss_PrinterInfo2 *pinfo2)
422 ADS_STATUS ads_rc;
423 TALLOC_CTX *ctx;
424 ADS_MODLIST mods;
425 struct GUID guid;
426 WERROR win_rc = WERR_OK;
427 const char *printer = pinfo2->sharename;
428 char *printer_dn = NULL;
430 /* build the ads mods */
431 ctx = talloc_init("nt_printer_publish_ads");
432 if (ctx == NULL) {
433 return WERR_NOMEM;
436 DEBUG(5, ("publishing printer %s\n", printer));
438 win_rc = nt_printer_dn_lookup(ctx, ads, printer, &printer_dn);
439 if (!W_ERROR_IS_OK(win_rc)) {
440 DEBUG(2, ("Failed to create printer dn\n"));
441 TALLOC_FREE(ctx);
442 return win_rc;
445 mods = ads_init_mods(ctx);
447 if (mods == NULL) {
448 TALLOC_FREE(ctx);
449 return WERR_NOMEM;
452 win_rc = nt_printer_info_to_mods(ctx, pinfo2, &mods);
453 if (!W_ERROR_IS_OK(win_rc)) {
454 TALLOC_FREE(ctx);
455 return win_rc;
458 /* publish it */
459 ads_rc = ads_mod_printer_entry(ads, printer_dn, ctx, &mods);
460 if (ads_rc.err.rc == LDAP_NO_SUCH_OBJECT) {
461 int i;
462 for (i=0; mods[i] != 0; i++)
464 mods[i] = (LDAPMod *)-1;
465 ads_rc = ads_add_printer_entry(ads, printer_dn, ctx, &mods);
468 if (!ADS_ERR_OK(ads_rc)) {
469 DEBUG(3, ("error publishing %s: %s\n",
470 printer, ads_errstr(ads_rc)));
473 win_rc = nt_printer_guid_retrieve_internal(ads, printer_dn, &guid);
474 if (!W_ERROR_IS_OK(win_rc)) {
475 TALLOC_FREE(ctx);
476 return win_rc;
479 /* TODO add a return value */
480 store_printer_guid(msg_ctx, printer, guid);
482 TALLOC_FREE(ctx);
484 return win_rc;
487 static WERROR nt_printer_unpublish_ads(ADS_STRUCT *ads,
488 const char *printer)
490 ADS_STATUS ads_rc;
491 LDAPMessage *res = NULL;
492 char *prt_dn = NULL;
494 DEBUG(5, ("unpublishing printer %s\n", printer));
496 /* remove the printer from the directory */
497 ads_rc = ads_find_printer_on_server(ads, &res,
498 printer, lp_netbios_name());
500 if (ADS_ERR_OK(ads_rc) && res && ads_count_replies(ads, res)) {
501 prt_dn = ads_get_dn(ads, talloc_tos(), res);
502 if (!prt_dn) {
503 ads_msgfree(ads, res);
504 return WERR_NOMEM;
506 ads_rc = ads_del_dn(ads, prt_dn);
507 TALLOC_FREE(prt_dn);
510 if (res) {
511 ads_msgfree(ads, res);
513 return WERR_OK;
516 /****************************************************************************
517 * Publish a printer in the directory
519 * @param mem_ctx memory context
520 * @param session_info session_info to access winreg pipe
521 * @param pinfo2 printer information
522 * @param action publish/unpublish action
523 * @return WERROR indicating status of publishing
524 ***************************************************************************/
526 WERROR nt_printer_publish(TALLOC_CTX *mem_ctx,
527 const struct auth_session_info *session_info,
528 struct messaging_context *msg_ctx,
529 struct spoolss_PrinterInfo2 *pinfo2,
530 int action)
532 uint32_t info2_mask = SPOOLSS_PRINTER_INFO_ATTRIBUTES;
533 struct spoolss_SetPrinterInfo2 *sinfo2;
534 ADS_STATUS ads_rc;
535 ADS_STRUCT *ads = NULL;
536 WERROR win_rc;
537 char *old_krb5ccname = NULL;
539 sinfo2 = talloc_zero(mem_ctx, struct spoolss_SetPrinterInfo2);
540 if (!sinfo2) {
541 return WERR_NOMEM;
544 switch (action) {
545 case DSPRINT_PUBLISH:
546 case DSPRINT_UPDATE:
547 pinfo2->attributes |= PRINTER_ATTRIBUTE_PUBLISHED;
548 break;
549 case DSPRINT_UNPUBLISH:
550 pinfo2->attributes &= (~PRINTER_ATTRIBUTE_PUBLISHED);
551 break;
552 default:
553 win_rc = WERR_NOT_SUPPORTED;
554 goto done;
557 sinfo2->attributes = pinfo2->attributes;
559 win_rc = winreg_update_printer_internal(mem_ctx, session_info, msg_ctx,
560 pinfo2->sharename, info2_mask,
561 sinfo2, NULL, NULL);
562 if (!W_ERROR_IS_OK(win_rc)) {
563 DEBUG(3, ("err %d saving data\n", W_ERROR_V(win_rc)));
564 goto done;
567 TALLOC_FREE(sinfo2);
569 ads = ads_init(lp_realm(), lp_workgroup(), NULL);
570 if (!ads) {
571 DEBUG(3, ("ads_init() failed\n"));
572 win_rc = WERR_SERVER_UNAVAILABLE;
573 goto done;
575 old_krb5ccname = getenv(KRB5_ENV_CCNAME);
576 setenv(KRB5_ENV_CCNAME, "MEMORY:prtpub_cache", 1);
577 SAFE_FREE(ads->auth.password);
578 ads->auth.password = secrets_fetch_machine_password(lp_workgroup(),
579 NULL, NULL);
581 /* ads_connect() will find the DC for us */
582 ads_rc = ads_connect(ads);
583 if (!ADS_ERR_OK(ads_rc)) {
584 DEBUG(3, ("ads_connect failed: %s\n", ads_errstr(ads_rc)));
585 win_rc = WERR_ACCESS_DENIED;
586 goto done;
589 switch (action) {
590 case DSPRINT_PUBLISH:
591 case DSPRINT_UPDATE:
592 win_rc = nt_printer_publish_ads(msg_ctx, ads, pinfo2);
593 break;
594 case DSPRINT_UNPUBLISH:
595 win_rc = nt_printer_unpublish_ads(ads, pinfo2->sharename);
596 break;
599 done:
600 ads_destroy(&ads);
601 ads_kdestroy("MEMORY:prtpub_cache");
602 unsetenv(KRB5_ENV_CCNAME);
603 if (old_krb5ccname) {
604 setenv(KRB5_ENV_CCNAME, old_krb5ccname, 0);
606 return win_rc;
609 WERROR check_published_printers(struct messaging_context *msg_ctx)
611 ADS_STATUS ads_rc;
612 ADS_STRUCT *ads = NULL;
613 int snum;
614 int n_services = lp_numservices();
615 TALLOC_CTX *tmp_ctx = NULL;
616 struct auth_session_info *session_info = NULL;
617 struct spoolss_PrinterInfo2 *pinfo2;
618 NTSTATUS status;
619 WERROR result;
620 char *old_krb5ccname = NULL;
622 tmp_ctx = talloc_new(NULL);
623 if (!tmp_ctx) return WERR_NOMEM;
625 ads = ads_init(lp_realm(), lp_workgroup(), NULL);
626 if (!ads) {
627 DEBUG(3, ("ads_init() failed\n"));
628 return WERR_SERVER_UNAVAILABLE;
630 old_krb5ccname = getenv(KRB5_ENV_CCNAME);
631 setenv(KRB5_ENV_CCNAME, "MEMORY:prtpub_cache", 1);
632 SAFE_FREE(ads->auth.password);
633 ads->auth.password = secrets_fetch_machine_password(lp_workgroup(),
634 NULL, NULL);
636 /* ads_connect() will find the DC for us */
637 ads_rc = ads_connect(ads);
638 if (!ADS_ERR_OK(ads_rc)) {
639 DEBUG(3, ("ads_connect failed: %s\n", ads_errstr(ads_rc)));
640 result = WERR_ACCESS_DENIED;
641 goto done;
644 status = make_session_info_system(tmp_ctx, &session_info);
645 if (!NT_STATUS_IS_OK(status)) {
646 DEBUG(0, ("check_published_printers: "
647 "Could not create system session_info\n"));
648 result = WERR_ACCESS_DENIED;
649 goto done;
652 for (snum = 0; snum < n_services; snum++) {
653 if (!lp_snum_ok(snum) || !lp_printable(snum)) {
654 continue;
657 result = winreg_get_printer_internal(tmp_ctx, session_info, msg_ctx,
658 lp_servicename(talloc_tos(), snum),
659 &pinfo2);
660 if (!W_ERROR_IS_OK(result)) {
661 continue;
664 if (pinfo2->attributes & PRINTER_ATTRIBUTE_PUBLISHED) {
665 nt_printer_publish_ads(msg_ctx, ads, pinfo2);
668 TALLOC_FREE(pinfo2);
671 result = WERR_OK;
672 done:
673 ads_destroy(&ads);
674 ads_kdestroy("MEMORY:prtpub_cache");
675 unsetenv(KRB5_ENV_CCNAME);
676 if (old_krb5ccname) {
677 setenv(KRB5_ENV_CCNAME, old_krb5ccname, 0);
679 talloc_free(tmp_ctx);
680 return result;
683 bool is_printer_published(TALLOC_CTX *mem_ctx,
684 const struct auth_session_info *session_info,
685 struct messaging_context *msg_ctx,
686 const char *servername,
687 const char *printer,
688 struct spoolss_PrinterInfo2 **info2)
690 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
691 WERROR result;
692 struct dcerpc_binding_handle *b;
694 result = winreg_printer_binding_handle(mem_ctx,
695 session_info,
696 msg_ctx,
697 &b);
698 if (!W_ERROR_IS_OK(result)) {
699 return false;
702 result = winreg_get_printer(mem_ctx, b,
703 printer, &pinfo2);
704 if (!W_ERROR_IS_OK(result)) {
705 return false;
708 if (!(pinfo2->attributes & PRINTER_ATTRIBUTE_PUBLISHED)) {
709 TALLOC_FREE(pinfo2);
710 return false;
713 if (info2) {
714 *info2 = talloc_move(mem_ctx, &pinfo2);
716 talloc_free(pinfo2);
717 return true;
719 #else
720 WERROR nt_printer_guid_retrieve(TALLOC_CTX *mem_ctx, const char *printer,
721 struct GUID *pguid)
723 return WERR_NOT_SUPPORTED;
726 WERROR nt_printer_guid_get(TALLOC_CTX *mem_ctx,
727 const struct auth_session_info *session_info,
728 struct messaging_context *msg_ctx,
729 const char *printer, struct GUID *guid)
731 return WERR_NOT_SUPPORTED;
734 WERROR nt_printer_publish(TALLOC_CTX *mem_ctx,
735 const struct auth_session_info *session_info,
736 struct messaging_context *msg_ctx,
737 struct spoolss_PrinterInfo2 *pinfo2,
738 int action)
740 return WERR_OK;
743 WERROR check_published_printers(struct messaging_context *msg_ctx)
745 return WERR_OK;
748 bool is_printer_published(TALLOC_CTX *mem_ctx,
749 const struct auth_session_info *session_info,
750 struct messaging_context *msg_ctx,
751 const char *servername,
752 const char *printer,
753 struct spoolss_PrinterInfo2 **info2)
755 return False;
757 #endif /* HAVE_ADS */