From 892d163635563a3505fcde2d3439a2f6b1af92a7 Mon Sep 17 00:00:00 2001
From: David Disseldorp <ddiss@samba.org>
Date: Thu, 18 Dec 2014 18:18:21 +0100
Subject: [PATCH 1/4] PATCHSET16: printing: split out printer DN and GUID
 retrieval

This functions are used for printer publishing.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=11018

Pair-programmed-with: Andreas Schneider <asn@samba.org>
Signed-off-by: David Disseldorp <ddiss@samba.org>
Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Guenther Deschner <gd@samba.org>
(cherry picked from commit 7cabd89789a50d37fc32735968c493092a37e69f)
---
 source3/printing/nt_printing_ads.c | 209 ++++++++++++++++++++++++-------------
 1 file changed, 137 insertions(+), 72 deletions(-)

diff --git a/source3/printing/nt_printing_ads.c b/source3/printing/nt_printing_ads.c
index bf309b0..25e1ab6 100644
--- a/source3/printing/nt_printing_ads.c
+++ b/source3/printing/nt_printing_ads.c
@@ -87,6 +87,128 @@ done:
 	talloc_free(tmp_ctx);
 }
 
+static WERROR nt_printer_dn_lookup(TALLOC_CTX *mem_ctx,
+				   ADS_STRUCT *ads,
+				   const char *printer,
+				   char **pprinter_dn)
+{
+	char *printer_dn = NULL;
+	char *srv_dn = NULL;
+	char *srv_cn_0 = NULL;
+	char *srv_cn_escaped = NULL;
+	char *sharename_escaped = NULL;
+	char *srv_dn_utf8 = NULL;
+	char **srv_cn_utf8 = NULL;
+	size_t converted_size;
+	ADS_STATUS ads_status;
+	LDAPMessage *res;
+	WERROR result;
+	bool ok;
+
+	ads_status = ads_find_machine_acct(ads, &res, global_myname());
+	if (!ADS_ERR_OK(ads_status)) {
+		DEBUG(2, ("Failed to find machine account for %s\n",
+			  global_myname()));
+		result = WERR_NOT_FOUND;
+		goto err_out;
+	}
+
+	/*
+	 * We use ldap_get_dn here as we need the answer in utf8 to call
+	 * ldap_explode_dn(). JRA.
+	 */
+	srv_dn_utf8 = ldap_get_dn((LDAP *)ads->ldap.ld, (LDAPMessage *)res);
+	ads_msgfree(ads, res);
+	if (srv_dn_utf8 == NULL) {
+		result = WERR_SERVER_UNAVAILABLE;
+		goto err_out;
+	}
+
+	srv_cn_utf8 = ldap_explode_dn(srv_dn_utf8, 1);
+	if (srv_cn_utf8 == NULL) {
+		ldap_memfree(srv_dn_utf8);
+		result = WERR_SERVER_UNAVAILABLE;
+		goto err_out;
+	}
+
+	/* Now convert to CH_UNIX. */
+	ok = pull_utf8_talloc(mem_ctx, &srv_dn, srv_dn_utf8, &converted_size);
+	ldap_memfree(srv_dn_utf8);
+	if (!ok) {
+		ldap_memfree(srv_cn_utf8);
+		result = WERR_SERVER_UNAVAILABLE;
+		goto err_out;
+	}
+
+	ok = pull_utf8_talloc(mem_ctx, &srv_cn_0, srv_cn_utf8[0], &converted_size);
+	ldap_memfree(srv_cn_utf8);
+	if (!ok) {
+		result = WERR_SERVER_UNAVAILABLE;
+		goto err_out;
+	}
+
+	srv_cn_escaped = escape_rdn_val_string_alloc(srv_cn_0);
+	if (srv_cn_escaped == NULL) {
+		result = WERR_SERVER_UNAVAILABLE;
+		goto err_out;
+	}
+
+	sharename_escaped = escape_rdn_val_string_alloc(printer);
+	if (sharename_escaped == NULL) {
+		result = WERR_SERVER_UNAVAILABLE;
+		goto err_out;
+	}
+
+	printer_dn = talloc_asprintf(mem_ctx,
+				     "cn=%s-%s,%s",
+				     srv_cn_escaped,
+				     sharename_escaped,
+				     srv_dn);
+	if (printer_dn == NULL) {
+		result = WERR_NOMEM;
+		goto err_out;
+	}
+
+	*pprinter_dn = printer_dn;
+
+	result = WERR_OK;
+err_out:
+	SAFE_FREE(sharename_escaped);
+	SAFE_FREE(srv_cn_escaped);
+	TALLOC_FREE(srv_cn_0);
+	TALLOC_FREE(srv_dn);
+	return result;
+}
+
+static WERROR nt_printer_guid_retrieve_internal(ADS_STRUCT *ads,
+						const char *printer_dn,
+						struct GUID *pguid)
+{
+	ADS_STATUS ads_status;
+	LDAPMessage *res;
+	const char *attrs[] = {"objectGUID", NULL};
+	struct GUID guid;
+	bool ok;
+
+	ads_status = ads_search_dn(ads, &res, printer_dn, attrs);
+	if (!ADS_ERR_OK(ads_status)) {
+		DEBUG(2, ("Failed to retrieve GUID from DC - %s\n",
+			  ads_errstr(ads_status)));
+		return WERR_BADFILE;
+	}
+
+	ZERO_STRUCT(guid);
+	ok = ads_pull_guid(ads, res, &guid);
+	ads_msgfree(ads, res);
+	if (!ok) {
+		return WERR_NOMEM;
+	}
+
+	*pguid = guid;
+
+	return WERR_OK;
+}
+
 WERROR nt_printer_guid_get(TALLOC_CTX *mem_ctx,
 			   const struct auth_serversupplied_info *session_info,
 			   struct messaging_context *msg_ctx,
@@ -246,16 +368,12 @@ static WERROR nt_printer_publish_ads(struct messaging_context *msg_ctx,
 				     struct spoolss_PrinterInfo2 *pinfo2)
 {
 	ADS_STATUS ads_rc;
-	LDAPMessage *res;
-	char *prt_dn = NULL, *srv_dn, *srv_cn_0, *srv_cn_escaped, *sharename_escaped;
-	char *srv_dn_utf8, **srv_cn_utf8;
 	TALLOC_CTX *ctx;
 	ADS_MODLIST mods;
-	const char *attrs[] = {"objectGUID", NULL};
 	struct GUID guid;
 	WERROR win_rc = WERR_OK;
-	size_t converted_size;
 	const char *printer = pinfo2->sharename;
+	char *printer_dn = NULL;
 
 	/* build the ads mods */
 	ctx = talloc_init("nt_printer_publish_ads");
@@ -265,65 +383,13 @@ static WERROR nt_printer_publish_ads(struct messaging_context *msg_ctx,
 
 	DEBUG(5, ("publishing printer %s\n", printer));
 
-	/* figure out where to publish */
-	ads_rc = ads_find_machine_acct(ads, &res, global_myname());
-	if (!ADS_ERR_OK(ads_rc)) {
-		DEBUG(0, ("failed to find machine account for %s\n",
-			  global_myname()));
-		TALLOC_FREE(ctx);
-		return WERR_NOT_FOUND;
-	}
-
-	/* We use ldap_get_dn here as we need the answer
-	 * in utf8 to call ldap_explode_dn(). JRA. */
-
-	srv_dn_utf8 = ldap_get_dn((LDAP *)ads->ldap.ld, (LDAPMessage *)res);
-	ads_msgfree(ads, res);
-	if (!srv_dn_utf8) {
-		TALLOC_FREE(ctx);
-		return WERR_SERVER_UNAVAILABLE;
-	}
-	srv_cn_utf8 = ldap_explode_dn(srv_dn_utf8, 1);
-	if (!srv_cn_utf8) {
-		TALLOC_FREE(ctx);
-		ldap_memfree(srv_dn_utf8);
-		return WERR_SERVER_UNAVAILABLE;
-	}
-	/* Now convert to CH_UNIX. */
-	if (!pull_utf8_talloc(ctx, &srv_dn, srv_dn_utf8, &converted_size)) {
-		TALLOC_FREE(ctx);
-		ldap_memfree(srv_dn_utf8);
-		ldap_memfree(srv_cn_utf8);
-		return WERR_SERVER_UNAVAILABLE;
-	}
-	if (!pull_utf8_talloc(ctx, &srv_cn_0, srv_cn_utf8[0], &converted_size)) {
-		TALLOC_FREE(ctx);
-		ldap_memfree(srv_dn_utf8);
-		ldap_memfree(srv_cn_utf8);
-		TALLOC_FREE(srv_dn);
-		return WERR_SERVER_UNAVAILABLE;
-	}
-
-	ldap_memfree(srv_dn_utf8);
-	ldap_memfree(srv_cn_utf8);
-
-	srv_cn_escaped = escape_rdn_val_string_alloc(srv_cn_0);
-	if (!srv_cn_escaped) {
-		TALLOC_FREE(ctx);
-		return WERR_SERVER_UNAVAILABLE;
-	}
-	sharename_escaped = escape_rdn_val_string_alloc(printer);
-	if (!sharename_escaped) {
-		SAFE_FREE(srv_cn_escaped);
+	win_rc = nt_printer_dn_lookup(ctx, ads, printer, &printer_dn);
+	if (!W_ERROR_IS_OK(win_rc)) {
+		DEBUG(2, ("Failed to create printer dn\n"));
 		TALLOC_FREE(ctx);
-		return WERR_SERVER_UNAVAILABLE;
+		return win_rc;
 	}
 
-	prt_dn = talloc_asprintf(ctx, "cn=%s-%s,%s", srv_cn_escaped, sharename_escaped, srv_dn);
-
-	SAFE_FREE(srv_cn_escaped);
-	SAFE_FREE(sharename_escaped);
-
 	mods = ads_init_mods(ctx);
 
 	if (mods == NULL) {
@@ -338,13 +404,13 @@ static WERROR nt_printer_publish_ads(struct messaging_context *msg_ctx,
 	}
 
 	/* publish it */
-	ads_rc = ads_mod_printer_entry(ads, prt_dn, ctx, &mods);
+	ads_rc = ads_mod_printer_entry(ads, printer_dn, ctx, &mods);
 	if (ads_rc.err.rc == LDAP_NO_SUCH_OBJECT) {
 		int i;
 		for (i=0; mods[i] != 0; i++)
 			;
 		mods[i] = (LDAPMod *)-1;
-		ads_rc = ads_add_printer_entry(ads, prt_dn, ctx, &mods);
+		ads_rc = ads_add_printer_entry(ads, printer_dn, ctx, &mods);
 	}
 
 	if (!ADS_ERR_OK(ads_rc)) {
@@ -352,16 +418,15 @@ static WERROR nt_printer_publish_ads(struct messaging_context *msg_ctx,
 			  printer, ads_errstr(ads_rc)));
 	}
 
-	/* retreive the guid and store it locally */
-	if (ADS_ERR_OK(ads_search_dn(ads, &res, prt_dn, attrs))) {
-		bool guid_ok;
-		ZERO_STRUCT(guid);
-		guid_ok = ads_pull_guid(ads, res, &guid);
-		ads_msgfree(ads, res);
-		if (guid_ok) {
-			store_printer_guid(msg_ctx, printer, guid);
-		}
+	win_rc = nt_printer_guid_retrieve_internal(ads, printer_dn, &guid);
+	if (!W_ERROR_IS_OK(win_rc)) {
+		TALLOC_FREE(ctx);
+		return win_rc;
 	}
+
+	/* TODO add a return value */
+	store_printer_guid(msg_ctx, printer, guid);
+
 	TALLOC_FREE(ctx);
 
 	return win_rc;
-- 
2.3.0


From 45bb946d93deaf4926754cf57454f79869e8bfaf Mon Sep 17 00:00:00 2001
From: David Disseldorp <ddiss@samba.org>
Date: Thu, 18 Dec 2014 18:23:11 +0100
Subject: [PATCH 2/4] PATCHSET16: printing: add nt_printer_guid_retrieve()
 helper

This function connects to the domain controller and retrieves the
GUID for the corresponding printer DN.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=11018

Pair-programmed-with: Andreas Schneider <asn@samba.org>
Signed-off-by: David Disseldorp <ddiss@samba.org>
Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Guenther Deschner <gd@samba.org>
(cherry picked from commit 38dbd054dc331a441b10fdebbdb4bd0fc51cfc0a)
---
 source3/include/nt_printing.h      |  3 ++
 source3/printing/nt_printing_ads.c | 58 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 61 insertions(+)

diff --git a/source3/include/nt_printing.h b/source3/include/nt_printing.h
index cdbad87..67a0522 100644
--- a/source3/include/nt_printing.h
+++ b/source3/include/nt_printing.h
@@ -132,6 +132,9 @@ bool print_access_check(const struct auth_serversupplied_info *server_info,
 			struct messaging_context *msg_ctx, int snum,
 			int access_type);
 
+WERROR nt_printer_guid_retrieve(TALLOC_CTX *mem_ctx, const char *printer,
+				struct GUID *pguid);
+
 WERROR nt_printer_guid_get(TALLOC_CTX *mem_ctx,
 			   const struct auth_serversupplied_info *server_info,
 			   struct messaging_context *msg_ctx,
diff --git a/source3/printing/nt_printing_ads.c b/source3/printing/nt_printing_ads.c
index 25e1ab6..6fa4bfc 100644
--- a/source3/printing/nt_printing_ads.c
+++ b/source3/printing/nt_printing_ads.c
@@ -209,6 +209,58 @@ static WERROR nt_printer_guid_retrieve_internal(ADS_STRUCT *ads,
 	return WERR_OK;
 }
 
+WERROR nt_printer_guid_retrieve(TALLOC_CTX *mem_ctx, const char *printer,
+				struct GUID *pguid)
+{
+	ADS_STRUCT *ads = NULL;
+	char *old_krb5ccname = NULL;
+	char *printer_dn;
+	WERROR result;
+	ADS_STATUS ads_status;
+	TALLOC_CTX *tmp_ctx;
+
+	tmp_ctx = talloc_new(mem_ctx);
+	if (tmp_ctx == NULL) {
+		return WERR_NOMEM;
+	}
+
+	ads = ads_init(lp_realm(), lp_workgroup(), NULL);
+	if (ads == NULL) {
+		result = WERR_SERVER_UNAVAILABLE;
+		goto out;
+	}
+
+	old_krb5ccname = getenv(KRB5_ENV_CCNAME);
+	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_status = ads_connect(ads);
+	if (!ADS_ERR_OK(ads_status)) {
+		DEBUG(3, ("ads_connect failed: %s\n", ads_errstr(ads_status)));
+		result = WERR_ACCESS_DENIED;
+		goto out;
+	}
+
+	result = nt_printer_dn_lookup(tmp_ctx, ads, printer, &printer_dn);
+	if (!W_ERROR_IS_OK(result)) {
+		goto out;
+	}
+
+	result = nt_printer_guid_retrieve_internal(ads, printer_dn, pguid);
+out:
+	TALLOC_FREE(tmp_ctx);
+	ads_destroy(&ads);
+	ads_kdestroy("MEMORY:prtpub_cache");
+	unsetenv(KRB5_ENV_CCNAME);
+	if (old_krb5ccname != NULL) {
+		setenv(KRB5_ENV_CCNAME, old_krb5ccname, 0);
+	}
+
+	return result;
+}
+
 WERROR nt_printer_guid_get(TALLOC_CTX *mem_ctx,
 			   const struct auth_serversupplied_info *session_info,
 			   struct messaging_context *msg_ctx,
@@ -652,6 +704,12 @@ bool is_printer_published(TALLOC_CTX *mem_ctx,
 	return true;
 }
 #else
+WERROR nt_printer_guid_retrieve(TALLOC_CTX *mem_ctx, const char *printer,
+				struct GUID *pguid)
+{
+	return WERR_NOT_SUPPORTED;
+}
+
 WERROR nt_printer_guid_get(TALLOC_CTX *mem_ctx,
 			   const struct auth_serversupplied_info *session_info,
 			   struct messaging_context *msg_ctx,
-- 
2.3.0


From 228323b1c846d6dfcd39e23c8ce850c79f339de9 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Thu, 18 Dec 2014 15:13:27 +0000
Subject: [PATCH 3/4] PATCHSET16: printing: rework nt_printer_guid_store to
 return errors

Callers can now choose whether or not to ignore errors.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=11018

Pair-programmed-with: David Disseldorp <ddiss@samba.org>
Signed-off-by: Andreas Schneider <asn@samba.org>
Signed-off-by: David Disseldorp <ddiss@samba.org>
Reviewed-by: Guenther Deschner <gd@samba.org>
(cherry picked from commit 6595ced146a53dcef9bbd5d2deb82a44c8ce1a1a)
---
 source3/include/nt_printing.h      |  3 +++
 source3/printing/nt_printing_ads.c | 49 +++++++++++++++++++++++++-------------
 2 files changed, 35 insertions(+), 17 deletions(-)

diff --git a/source3/include/nt_printing.h b/source3/include/nt_printing.h
index 67a0522..493f4ce 100644
--- a/source3/include/nt_printing.h
+++ b/source3/include/nt_printing.h
@@ -135,6 +135,9 @@ bool print_access_check(const struct auth_serversupplied_info *server_info,
 WERROR nt_printer_guid_retrieve(TALLOC_CTX *mem_ctx, const char *printer,
 				struct GUID *pguid);
 
+WERROR nt_printer_guid_store(struct messaging_context *msg_ctx,
+			     const char *printer, struct GUID guid);
+
 WERROR nt_printer_guid_get(TALLOC_CTX *mem_ctx,
 			   const struct auth_serversupplied_info *server_info,
 			   struct messaging_context *msg_ctx,
diff --git a/source3/printing/nt_printing_ads.c b/source3/printing/nt_printing_ads.c
index 6fa4bfc..540a8a3 100644
--- a/source3/printing/nt_printing_ads.c
+++ b/source3/printing/nt_printing_ads.c
@@ -35,32 +35,32 @@
 /*****************************************************************
  ****************************************************************/
 
-static void store_printer_guid(struct messaging_context *msg_ctx,
-			       const char *printer, struct GUID guid)
+WERROR nt_printer_guid_store(struct messaging_context *msg_ctx,
+			     const char *printer, struct GUID guid)
 {
 	TALLOC_CTX *tmp_ctx;
-	struct auth_serversupplied_info *session_info = NULL;
+	const struct auth_serversupplied_info *session_info;
 	const char *guid_str;
 	DATA_BLOB blob;
-	NTSTATUS status;
 	WERROR result;
 
 	tmp_ctx = talloc_new(NULL);
 	if (!tmp_ctx) {
-		DEBUG(0, ("store_printer_guid: Out of memory?!\n"));
-		return;
+		DEBUG(0, ("Out of memory?!\n"));
+		return WERR_NOMEM;
 	}
 
-	status = make_session_info_system(tmp_ctx, &session_info);
-	if (!NT_STATUS_IS_OK(status)) {
-		DEBUG(0, ("store_printer_guid: "
-			  "Could not create system session_info\n"));
+	session_info = get_session_info_system();
+	if (session_info == NULL) {
+		DEBUG(0, ("Could not get system session_info\n"));
+		result = WERR_NOMEM;
 		goto done;
 	}
 
 	guid_str = GUID_string(tmp_ctx, &guid);
 	if (!guid_str) {
-		DEBUG(0, ("store_printer_guid: Out of memory?!\n"));
+		DEBUG(0, ("Out of memory?!\n"));
+		result = WERR_NOMEM;
 		goto done;
 	}
 
@@ -68,9 +68,9 @@ static void store_printer_guid(struct messaging_context *msg_ctx,
 	   Vista to whine */
 
 	if (!push_reg_sz(tmp_ctx, &blob, guid_str)) {
-		DEBUG(0, ("store_printer_guid: "
-			  "Could not marshall string %s for objectGUID\n",
+		DEBUG(0, ("Could not marshall string %s for objectGUID\n",
 			  guid_str));
+		result = WERR_NOMEM;
 		goto done;
 	}
 
@@ -79,12 +79,15 @@ static void store_printer_guid(struct messaging_context *msg_ctx,
 					   SPOOL_DSSPOOLER_KEY, "objectGUID",
 					   REG_SZ, blob.data, blob.length);
 	if (!W_ERROR_IS_OK(result)) {
-		DEBUG(0, ("store_printer_guid: "
-			  "Failed to store GUID for printer %s\n", printer));
+		DEBUG(0, ("Failed to store GUID for printer %s\n", printer));
+		goto done;
 	}
 
+	result = WERR_OK;
 done:
 	talloc_free(tmp_ctx);
+
+	return result;
 }
 
 static WERROR nt_printer_dn_lookup(TALLOC_CTX *mem_ctx,
@@ -468,6 +471,7 @@ static WERROR nt_printer_publish_ads(struct messaging_context *msg_ctx,
 	if (!ADS_ERR_OK(ads_rc)) {
 		DEBUG(3, ("error publishing %s: %s\n",
 			  printer, ads_errstr(ads_rc)));
+		/* XXX failed to publish, so no guid to retrieve */
 	}
 
 	win_rc = nt_printer_guid_retrieve_internal(ads, printer_dn, &guid);
@@ -476,8 +480,13 @@ static WERROR nt_printer_publish_ads(struct messaging_context *msg_ctx,
 		return win_rc;
 	}
 
-	/* TODO add a return value */
-	store_printer_guid(msg_ctx, printer, guid);
+	win_rc = nt_printer_guid_store(msg_ctx, printer, guid);
+	if (!W_ERROR_IS_OK(win_rc)) {
+		DEBUG(3, ("failed to store printer %s guid\n",
+			  printer));
+		/* not catastrophic, retrieve on next use */
+		win_rc = WERR_OK;
+	}
 
 	TALLOC_FREE(ctx);
 
@@ -704,6 +713,12 @@ bool is_printer_published(TALLOC_CTX *mem_ctx,
 	return true;
 }
 #else
+WERROR nt_printer_guid_store(struct messaging_context *msg_ctx,
+			   const char *printer, struct GUID guid)
+{
+	return WERR_NOT_SUPPORTED;
+}
+
 WERROR nt_printer_guid_retrieve(TALLOC_CTX *mem_ctx, const char *printer,
 				struct GUID *pguid)
 {
-- 
2.3.0


From d4847deadc4cd6f4f8071fae16d05bc8ec4ed566 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Thu, 18 Dec 2014 15:14:36 +0000
Subject: [PATCH 4/4] PATCHSET16: spoolss: retrieve published printer GUID if
 not in registry
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

When a printer is published, the GUID for the published DN is retrieved
from the domain controller and stored in the registry.
When handling a spoolss GetPrinter(level=7) request, the same GUID is
obtained from the registry and returned to the client.

This change sees the spoolss server query the DC for the published
printer GUID if it is not present in the registry when handling a
spoolss GetPrinter(level=7) request.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=11018

Pair-Programmed-With: David Disseldorp <ddiss@samba.org>
Signed-off-by: Andreas Schneider <asn@samba.org>
Signed-off-by: David Disseldorp <ddiss@samba.org>
Reviewed-by: Guenther Deschner <gd@samba.org>

Autobuild-User(master): Günther Deschner <gd@samba.org>
Autobuild-Date(master): Wed Feb 18 12:43:44 CET 2015 on sn-devel-104

(cherry picked from commit a4157e7c5d75be7003ad0b72fdfe9856a9e5ba8f)
---
 source3/rpc_server/spoolss/srv_spoolss_nt.c | 20 +++++++++++++++++++-
 1 file changed, 19 insertions(+), 1 deletion(-)

diff --git a/source3/rpc_server/spoolss/srv_spoolss_nt.c b/source3/rpc_server/spoolss/srv_spoolss_nt.c
index 0c4b582..516b7dc 100644
--- a/source3/rpc_server/spoolss/srv_spoolss_nt.c
+++ b/source3/rpc_server/spoolss/srv_spoolss_nt.c
@@ -4213,7 +4213,25 @@ static WERROR construct_printer_info7(TALLOC_CTX *mem_ctx,
 		werr = nt_printer_guid_get(tmp_ctx, session_info, msg_ctx,
 					   printer, &guid);
 		if (!W_ERROR_IS_OK(werr)) {
-			goto out_tmp_free;
+			/*
+			 * If we do not have a GUID entry in the registry, then
+			 * try to retrieve it from AD and store it now.
+			 */
+			werr = nt_printer_guid_retrieve(tmp_ctx, printer,
+							&guid);
+			if (!W_ERROR_IS_OK(werr)) {
+				DEBUG(1, ("Failed to retrieve GUID for "
+					  "printer [%s] from AD - "
+					  "Is the the printer still "
+					  "published ?\n", printer));
+				goto out_tmp_free;
+			}
+
+			werr = nt_printer_guid_store(msg_ctx, printer, guid);
+			if (!W_ERROR_IS_OK(werr)) {
+				DEBUG(3, ("failed to store printer %s guid\n",
+					  printer));
+			}
 		}
 		r->guid = talloc_strdup_upper(mem_ctx, GUID_string2(mem_ctx, &guid));
 		r->action = DSPRINT_PUBLISH;
-- 
2.3.0

