s3:libnet: Require sealed LDAP SASL connections for joining
[Samba.git] / source3 / printing / nt_printing_ads.c
bloba82f1361fc83f8e3d88119f72f3c287e5d38a899
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 WERROR nt_printer_guid_store(struct messaging_context *msg_ctx,
39 const char *printer, struct GUID guid)
41 TALLOC_CTX *tmp_ctx;
42 const struct auth_session_info *session_info;
43 const char *guid_str;
44 DATA_BLOB blob;
45 WERROR result;
47 tmp_ctx = talloc_new(NULL);
48 if (!tmp_ctx) {
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;
57 goto done;
60 guid_str = GUID_string(tmp_ctx, &guid);
61 if (!guid_str) {
62 DEBUG(0, ("Out of memory?!\n"));
63 result = WERR_NOT_ENOUGH_MEMORY;
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, ("Could not marshall string %s for objectGUID\n",
72 guid_str));
73 result = WERR_NOT_ENOUGH_MEMORY;
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, ("Failed to store GUID for printer %s\n", printer));
83 goto done;
86 result = WERR_OK;
87 done:
88 talloc_free(tmp_ctx);
90 return result;
93 static WERROR nt_printer_dn_lookup(TALLOC_CTX *mem_ctx,
94 ADS_STRUCT *ads,
95 const char *printer,
96 char **pprinter_dn)
98 char *printer_dn = NULL;
99 char *srv_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;
107 LDAPMessage *res;
108 WERROR result;
109 bool ok;
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",
114 lp_netbios_name()));
115 result = WERR_NOT_FOUND;
116 goto err_out;
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;
127 goto err_out;
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;
134 goto err_out;
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);
140 if (!ok) {
141 ldap_memfree(srv_cn_utf8);
142 result = WERR_RPC_S_SERVER_UNAVAILABLE;
143 goto err_out;
146 ok = pull_utf8_talloc(mem_ctx, &srv_cn_0, srv_cn_utf8[0], &converted_size);
147 ldap_memfree(srv_cn_utf8);
148 if (!ok) {
149 result = WERR_RPC_S_SERVER_UNAVAILABLE;
150 goto err_out;
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;
156 goto err_out;
159 sharename_escaped = escape_rdn_val_string_alloc(printer);
160 if (sharename_escaped == NULL) {
161 result = WERR_RPC_S_SERVER_UNAVAILABLE;
162 goto err_out;
165 printer_dn = talloc_asprintf(mem_ctx,
166 "cn=%s-%s,%s",
167 srv_cn_escaped,
168 sharename_escaped,
169 srv_dn);
170 if (printer_dn == NULL) {
171 result = WERR_NOT_ENOUGH_MEMORY;
172 goto err_out;
175 *pprinter_dn = printer_dn;
177 result = WERR_OK;
178 err_out:
179 SAFE_FREE(sharename_escaped);
180 SAFE_FREE(srv_cn_escaped);
181 TALLOC_FREE(srv_cn_0);
182 TALLOC_FREE(srv_dn);
183 return result;
186 static WERROR nt_printer_guid_retrieve_internal(ADS_STRUCT *ads,
187 const char *printer_dn,
188 struct GUID *pguid)
190 ADS_STATUS ads_status;
191 LDAPMessage *res;
192 const char *attrs[] = {"objectGUID", NULL};
193 struct GUID guid;
194 bool ok;
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;
203 ZERO_STRUCT(guid);
204 ok = ads_pull_guid(ads, res, &guid);
205 ads_msgfree(ads, res);
206 if (!ok) {
207 return WERR_NOT_ENOUGH_MEMORY;
210 *pguid = guid;
212 return WERR_OK;
215 WERROR nt_printer_guid_retrieve(TALLOC_CTX *mem_ctx, const char *printer,
216 struct GUID *pguid)
218 ADS_STRUCT *ads = NULL;
219 char *old_krb5ccname = NULL;
220 char *printer_dn;
221 WERROR result;
222 ADS_STATUS ads_status;
223 TALLOC_CTX *tmp_ctx;
225 tmp_ctx = talloc_new(mem_ctx);
226 if (tmp_ctx == NULL) {
227 return WERR_NOT_ENOUGH_MEMORY;
230 ads = ads_init(lp_realm(), lp_workgroup(), NULL, ADS_SASL_PLAIN);
231 if (ads == NULL) {
232 result = WERR_RPC_S_SERVER_UNAVAILABLE;
233 goto out;
236 old_krb5ccname = getenv(KRB5_ENV_CCNAME);
237 setenv(KRB5_ENV_CCNAME, "MEMORY:prtpub_cache", 1);
238 SAFE_FREE(ads->auth.password);
239 ads->auth.password = secrets_fetch_machine_password(lp_workgroup(),
240 NULL, NULL);
242 ads_status = ads_connect(ads);
243 if (!ADS_ERR_OK(ads_status)) {
244 DEBUG(3, ("ads_connect failed: %s\n", ads_errstr(ads_status)));
245 result = WERR_ACCESS_DENIED;
246 goto out;
249 result = nt_printer_dn_lookup(tmp_ctx, ads, printer, &printer_dn);
250 if (!W_ERROR_IS_OK(result)) {
251 goto out;
254 result = nt_printer_guid_retrieve_internal(ads, printer_dn, pguid);
255 out:
256 TALLOC_FREE(tmp_ctx);
257 ads_destroy(&ads);
258 ads_kdestroy("MEMORY:prtpub_cache");
259 unsetenv(KRB5_ENV_CCNAME);
260 if (old_krb5ccname != NULL) {
261 setenv(KRB5_ENV_CCNAME, old_krb5ccname, 0);
264 return result;
267 WERROR nt_printer_guid_get(TALLOC_CTX *mem_ctx,
268 const struct auth_session_info *session_info,
269 struct messaging_context *msg_ctx,
270 const char *printer, struct GUID *guid)
272 TALLOC_CTX *tmp_ctx;
273 enum winreg_Type type;
274 DATA_BLOB blob;
275 uint32_t len;
276 NTSTATUS status;
277 WERROR result;
279 tmp_ctx = talloc_new(mem_ctx);
280 if (tmp_ctx == NULL) {
281 DEBUG(0, ("out of memory?!\n"));
282 return WERR_NOT_ENOUGH_MEMORY;
285 result = winreg_get_printer_dataex_internal(tmp_ctx, session_info,
286 msg_ctx, printer,
287 SPOOL_DSSPOOLER_KEY,
288 "objectGUID",
289 &type,
290 &blob.data,
291 &len);
292 if (!W_ERROR_IS_OK(result)) {
293 DEBUG(0, ("Failed to get GUID for printer %s\n", printer));
294 goto out_ctx_free;
296 blob.length = (size_t)len;
298 /* We used to store the guid as REG_BINARY, then swapped
299 to REG_SZ for Vista compatibility so check for both */
301 switch (type) {
302 case REG_SZ: {
303 bool ok;
304 const char *guid_str;
305 ok = pull_reg_sz(tmp_ctx, &blob, &guid_str);
306 if (!ok) {
307 DEBUG(0, ("Failed to unmarshall GUID for printer %s\n",
308 printer));
309 result = WERR_REGISTRY_CORRUPT;
310 goto out_ctx_free;
312 status = GUID_from_string(guid_str, guid);
313 if (!NT_STATUS_IS_OK(status)) {
314 DEBUG(0, ("bad GUID for printer %s\n", printer));
315 result = ntstatus_to_werror(status);
316 goto out_ctx_free;
318 break;
320 case REG_BINARY:
321 if (blob.length != sizeof(struct GUID)) {
322 DEBUG(0, ("bad GUID for printer %s\n", printer));
323 result = WERR_REGISTRY_CORRUPT;
324 goto out_ctx_free;
326 memcpy(guid, blob.data, sizeof(struct GUID));
327 break;
328 default:
329 DEBUG(0,("GUID value stored as invalid type (%d)\n", type));
330 result = WERR_REGISTRY_CORRUPT;
331 goto out_ctx_free;
332 break;
334 result = WERR_OK;
336 out_ctx_free:
337 talloc_free(tmp_ctx);
338 return result;
341 static WERROR nt_printer_info_to_mods(TALLOC_CTX *ctx,
342 struct spoolss_PrinterInfo2 *info2,
343 ADS_MODLIST *mods)
345 char *info_str;
347 ads_mod_str(ctx, mods, SPOOL_REG_PRINTERNAME, info2->sharename);
348 ads_mod_str(ctx, mods, SPOOL_REG_SHORTSERVERNAME, lp_netbios_name());
349 ads_mod_str(ctx, mods, SPOOL_REG_SERVERNAME, get_mydnsfullname());
351 info_str = talloc_asprintf(ctx, "\\\\%s\\%s",
352 get_mydnsfullname(), info2->sharename);
353 if (info_str == NULL) {
354 return WERR_NOT_ENOUGH_MEMORY;
356 ads_mod_str(ctx, mods, SPOOL_REG_UNCNAME, info_str);
358 info_str = talloc_asprintf(ctx, "%d", 4);
359 if (info_str == NULL) {
360 return WERR_NOT_ENOUGH_MEMORY;
362 ads_mod_str(ctx, mods, SPOOL_REG_VERSIONNUMBER, info_str);
364 /* empty strings in the mods list result in an attrubute error */
365 if (strlen(info2->drivername) != 0)
366 ads_mod_str(ctx, mods, SPOOL_REG_DRIVERNAME, info2->drivername);
367 if (strlen(info2->location) != 0)
368 ads_mod_str(ctx, mods, SPOOL_REG_LOCATION, info2->location);
369 if (strlen(info2->comment) != 0)
370 ads_mod_str(ctx, mods, SPOOL_REG_DESCRIPTION, info2->comment);
371 if (strlen(info2->portname) != 0)
372 ads_mod_str(ctx, mods, SPOOL_REG_PORTNAME, info2->portname);
373 if (strlen(info2->sepfile) != 0)
374 ads_mod_str(ctx, mods, SPOOL_REG_PRINTSEPARATORFILE, info2->sepfile);
376 info_str = talloc_asprintf(ctx, "%u", info2->starttime);
377 if (info_str == NULL) {
378 return WERR_NOT_ENOUGH_MEMORY;
380 ads_mod_str(ctx, mods, SPOOL_REG_PRINTSTARTTIME, info_str);
382 info_str = talloc_asprintf(ctx, "%u", info2->untiltime);
383 if (info_str == NULL) {
384 return WERR_NOT_ENOUGH_MEMORY;
386 ads_mod_str(ctx, mods, SPOOL_REG_PRINTENDTIME, info_str);
388 info_str = talloc_asprintf(ctx, "%u", info2->priority);
389 if (info_str == NULL) {
390 return WERR_NOT_ENOUGH_MEMORY;
392 ads_mod_str(ctx, mods, SPOOL_REG_PRIORITY, info_str);
394 if (info2->attributes & PRINTER_ATTRIBUTE_KEEPPRINTEDJOBS) {
395 ads_mod_str(ctx, mods, SPOOL_REG_PRINTKEEPPRINTEDJOBS, "TRUE");
396 } else {
397 ads_mod_str(ctx, mods, SPOOL_REG_PRINTKEEPPRINTEDJOBS, "FALSE");
400 switch (info2->attributes & 0x3) {
401 case 0:
402 ads_mod_str(ctx, mods, SPOOL_REG_PRINTSPOOLING,
403 SPOOL_REGVAL_PRINTWHILESPOOLING);
404 break;
405 case 1:
406 ads_mod_str(ctx, mods, SPOOL_REG_PRINTSPOOLING,
407 SPOOL_REGVAL_PRINTAFTERSPOOLED);
408 break;
409 case 2:
410 ads_mod_str(ctx, mods, SPOOL_REG_PRINTSPOOLING,
411 SPOOL_REGVAL_PRINTDIRECT);
412 break;
413 default:
414 DEBUG(3, ("unsupported printer attributes %x\n",
415 info2->attributes));
418 return WERR_OK;
421 static WERROR nt_printer_publish_ads(struct messaging_context *msg_ctx,
422 ADS_STRUCT *ads,
423 struct spoolss_PrinterInfo2 *pinfo2)
425 ADS_STATUS ads_rc;
426 TALLOC_CTX *ctx;
427 ADS_MODLIST mods;
428 struct GUID guid;
429 WERROR win_rc = WERR_OK;
430 const char *printer = pinfo2->sharename;
431 char *printer_dn = NULL;
433 /* build the ads mods */
434 ctx = talloc_init("nt_printer_publish_ads");
435 if (ctx == NULL) {
436 return WERR_NOT_ENOUGH_MEMORY;
439 DEBUG(5, ("publishing printer %s\n", printer));
441 win_rc = nt_printer_dn_lookup(ctx, ads, printer, &printer_dn);
442 if (!W_ERROR_IS_OK(win_rc)) {
443 DEBUG(2, ("Failed to create printer dn\n"));
444 TALLOC_FREE(ctx);
445 return win_rc;
448 mods = ads_init_mods(ctx);
450 if (mods == NULL) {
451 TALLOC_FREE(ctx);
452 return WERR_NOT_ENOUGH_MEMORY;
455 win_rc = nt_printer_info_to_mods(ctx, pinfo2, &mods);
456 if (!W_ERROR_IS_OK(win_rc)) {
457 TALLOC_FREE(ctx);
458 return win_rc;
461 /* publish it */
462 ads_rc = ads_mod_printer_entry(ads, printer_dn, ctx, &mods);
463 if (ads_rc.err.rc == LDAP_NO_SUCH_OBJECT) {
464 int i;
465 for (i=0; mods[i] != 0; i++)
467 mods[i] = (LDAPMod *)-1;
468 ads_rc = ads_add_printer_entry(ads, printer_dn, ctx, &mods);
471 if (!ADS_ERR_OK(ads_rc)) {
472 DEBUG(3, ("error publishing %s: %s\n",
473 printer, ads_errstr(ads_rc)));
474 /* XXX failed to publish, so no guid to retrieve */
477 win_rc = nt_printer_guid_retrieve_internal(ads, printer_dn, &guid);
478 if (!W_ERROR_IS_OK(win_rc)) {
479 TALLOC_FREE(ctx);
480 return win_rc;
483 win_rc = nt_printer_guid_store(msg_ctx, printer, guid);
484 if (!W_ERROR_IS_OK(win_rc)) {
485 DEBUG(3, ("failed to store printer %s guid\n",
486 printer));
487 /* not catastrophic, retrieve on next use */
488 win_rc = WERR_OK;
491 TALLOC_FREE(ctx);
493 return win_rc;
496 static WERROR nt_printer_unpublish_ads(ADS_STRUCT *ads,
497 const char *printer)
499 ADS_STATUS ads_rc;
500 LDAPMessage *res = NULL;
501 char *prt_dn = NULL;
503 DEBUG(5, ("unpublishing printer %s\n", printer));
505 /* remove the printer from the directory */
506 ads_rc = ads_find_printer_on_server(ads, &res,
507 printer, lp_netbios_name());
509 if (ADS_ERR_OK(ads_rc) && res && ads_count_replies(ads, res)) {
510 prt_dn = ads_get_dn(ads, talloc_tos(), res);
511 if (!prt_dn) {
512 ads_msgfree(ads, res);
513 return WERR_NOT_ENOUGH_MEMORY;
515 ads_rc = ads_del_dn(ads, prt_dn);
516 TALLOC_FREE(prt_dn);
519 if (res) {
520 ads_msgfree(ads, res);
522 return WERR_OK;
525 /****************************************************************************
526 * Publish a printer in the directory
528 * @param mem_ctx memory context
529 * @param session_info session_info to access winreg pipe
530 * @param pinfo2 printer information
531 * @param action publish/unpublish action
532 * @return WERROR indicating status of publishing
533 ***************************************************************************/
535 WERROR nt_printer_publish(TALLOC_CTX *mem_ctx,
536 const struct auth_session_info *session_info,
537 struct messaging_context *msg_ctx,
538 struct spoolss_PrinterInfo2 *pinfo2,
539 int action)
541 uint32_t info2_mask = SPOOLSS_PRINTER_INFO_ATTRIBUTES;
542 struct spoolss_SetPrinterInfo2 *sinfo2;
543 ADS_STATUS ads_rc;
544 ADS_STRUCT *ads = NULL;
545 WERROR win_rc;
546 char *old_krb5ccname = NULL;
548 sinfo2 = talloc_zero(mem_ctx, struct spoolss_SetPrinterInfo2);
549 if (!sinfo2) {
550 return WERR_NOT_ENOUGH_MEMORY;
553 switch (action) {
554 case DSPRINT_PUBLISH:
555 case DSPRINT_UPDATE:
556 pinfo2->attributes |= PRINTER_ATTRIBUTE_PUBLISHED;
557 break;
558 case DSPRINT_UNPUBLISH:
559 pinfo2->attributes &= (~PRINTER_ATTRIBUTE_PUBLISHED);
560 break;
561 default:
562 win_rc = WERR_NOT_SUPPORTED;
563 goto done;
566 sinfo2->attributes = pinfo2->attributes;
568 win_rc = winreg_update_printer_internal(mem_ctx, session_info, msg_ctx,
569 pinfo2->sharename, info2_mask,
570 sinfo2, NULL, NULL);
571 if (!W_ERROR_IS_OK(win_rc)) {
572 DBG_NOTICE("Failed to update data for printer [%s] - %s\n",
573 pinfo2->sharename,
574 win_errstr(win_rc));
575 goto done;
578 TALLOC_FREE(sinfo2);
580 ads = ads_init(lp_realm(), lp_workgroup(), NULL, ADS_SASL_PLAIN);
581 if (!ads) {
582 DEBUG(3, ("ads_init() failed\n"));
583 win_rc = WERR_RPC_S_SERVER_UNAVAILABLE;
584 goto done;
586 old_krb5ccname = getenv(KRB5_ENV_CCNAME);
587 setenv(KRB5_ENV_CCNAME, "MEMORY:prtpub_cache", 1);
588 SAFE_FREE(ads->auth.password);
589 ads->auth.password = secrets_fetch_machine_password(lp_workgroup(),
590 NULL, NULL);
592 /* ads_connect() will find the DC for us */
593 ads_rc = ads_connect(ads);
594 if (!ADS_ERR_OK(ads_rc)) {
595 DEBUG(3, ("ads_connect failed: %s\n", ads_errstr(ads_rc)));
596 win_rc = WERR_ACCESS_DENIED;
597 goto done;
600 switch (action) {
601 case DSPRINT_PUBLISH:
602 case DSPRINT_UPDATE:
603 win_rc = nt_printer_publish_ads(msg_ctx, ads, pinfo2);
604 break;
605 case DSPRINT_UNPUBLISH:
606 win_rc = nt_printer_unpublish_ads(ads, pinfo2->sharename);
607 break;
610 done:
611 ads_destroy(&ads);
612 ads_kdestroy("MEMORY:prtpub_cache");
613 unsetenv(KRB5_ENV_CCNAME);
614 if (old_krb5ccname) {
615 setenv(KRB5_ENV_CCNAME, old_krb5ccname, 0);
617 return win_rc;
620 WERROR check_published_printers(struct messaging_context *msg_ctx)
622 ADS_STATUS ads_rc;
623 ADS_STRUCT *ads = NULL;
624 int snum;
625 int n_services = lp_numservices();
626 TALLOC_CTX *tmp_ctx = NULL;
627 struct auth_session_info *session_info = NULL;
628 struct spoolss_PrinterInfo2 *pinfo2;
629 NTSTATUS status;
630 WERROR result;
631 char *old_krb5ccname = NULL;
633 tmp_ctx = talloc_new(NULL);
634 if (!tmp_ctx) return WERR_NOT_ENOUGH_MEMORY;
636 ads = ads_init(lp_realm(), lp_workgroup(), NULL, ADS_SASL_PLAIN);
637 if (!ads) {
638 DEBUG(3, ("ads_init() failed\n"));
639 return WERR_RPC_S_SERVER_UNAVAILABLE;
641 old_krb5ccname = getenv(KRB5_ENV_CCNAME);
642 setenv(KRB5_ENV_CCNAME, "MEMORY:prtpub_cache", 1);
643 SAFE_FREE(ads->auth.password);
644 ads->auth.password = secrets_fetch_machine_password(lp_workgroup(),
645 NULL, NULL);
647 /* ads_connect() will find the DC for us */
648 ads_rc = ads_connect(ads);
649 if (!ADS_ERR_OK(ads_rc)) {
650 DEBUG(3, ("ads_connect failed: %s\n", ads_errstr(ads_rc)));
651 result = WERR_ACCESS_DENIED;
652 goto done;
655 status = make_session_info_system(tmp_ctx, &session_info);
656 if (!NT_STATUS_IS_OK(status)) {
657 DEBUG(0, ("check_published_printers: "
658 "Could not create system session_info\n"));
659 result = WERR_ACCESS_DENIED;
660 goto done;
663 for (snum = 0; snum < n_services; snum++) {
664 if (!lp_snum_ok(snum) || !lp_printable(snum)) {
665 continue;
668 result = winreg_get_printer_internal(tmp_ctx, session_info, msg_ctx,
669 lp_servicename(talloc_tos(), snum),
670 &pinfo2);
671 if (!W_ERROR_IS_OK(result)) {
672 continue;
675 if (pinfo2->attributes & PRINTER_ATTRIBUTE_PUBLISHED) {
676 nt_printer_publish_ads(msg_ctx, ads, pinfo2);
679 TALLOC_FREE(pinfo2);
682 result = WERR_OK;
683 done:
684 ads_destroy(&ads);
685 ads_kdestroy("MEMORY:prtpub_cache");
686 unsetenv(KRB5_ENV_CCNAME);
687 if (old_krb5ccname) {
688 setenv(KRB5_ENV_CCNAME, old_krb5ccname, 0);
690 talloc_free(tmp_ctx);
691 return result;
694 bool is_printer_published(TALLOC_CTX *mem_ctx,
695 const struct auth_session_info *session_info,
696 struct messaging_context *msg_ctx,
697 const char *servername,
698 const char *printer,
699 struct spoolss_PrinterInfo2 **info2)
701 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
702 WERROR result;
703 struct dcerpc_binding_handle *b;
705 result = winreg_printer_binding_handle(mem_ctx,
706 session_info,
707 msg_ctx,
708 &b);
709 if (!W_ERROR_IS_OK(result)) {
710 return false;
713 result = winreg_get_printer(mem_ctx, b,
714 printer, &pinfo2);
715 if (!W_ERROR_IS_OK(result)) {
716 return false;
719 if (!(pinfo2->attributes & PRINTER_ATTRIBUTE_PUBLISHED)) {
720 TALLOC_FREE(pinfo2);
721 return false;
724 if (info2) {
725 *info2 = talloc_move(mem_ctx, &pinfo2);
727 talloc_free(pinfo2);
728 return true;
730 #else
731 WERROR nt_printer_guid_store(struct messaging_context *msg_ctx,
732 const char *printer, struct GUID guid)
734 return WERR_NOT_SUPPORTED;
737 WERROR nt_printer_guid_retrieve(TALLOC_CTX *mem_ctx, const char *printer,
738 struct GUID *pguid)
740 return WERR_NOT_SUPPORTED;
743 WERROR nt_printer_guid_get(TALLOC_CTX *mem_ctx,
744 const struct auth_session_info *session_info,
745 struct messaging_context *msg_ctx,
746 const char *printer, struct GUID *guid)
748 return WERR_NOT_SUPPORTED;
751 WERROR nt_printer_publish(TALLOC_CTX *mem_ctx,
752 const struct auth_session_info *session_info,
753 struct messaging_context *msg_ctx,
754 struct spoolss_PrinterInfo2 *pinfo2,
755 int action)
757 return WERR_OK;
760 WERROR check_published_printers(struct messaging_context *msg_ctx)
762 return WERR_OK;
765 bool is_printer_published(TALLOC_CTX *mem_ctx,
766 const struct auth_session_info *session_info,
767 struct messaging_context *msg_ctx,
768 const char *servername,
769 const char *printer,
770 struct spoolss_PrinterInfo2 **info2)
772 return False;
774 #endif /* HAVE_ADS */