printing: split out printer DN and GUID retrieval
authorDavid Disseldorp <ddiss@samba.org>
Thu, 18 Dec 2014 17:18:21 +0000 (18:18 +0100)
committerGünther Deschner <gd@samba.org>
Wed, 18 Feb 2015 09:14:09 +0000 (10:14 +0100)
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>
source3/printing/nt_printing_ads.c

index 5a5a17751d844d97e0985f595a74dcd58e7677d9..c136a70c034d38c98fecc4d10d4ff58504d05ce5 100644 (file)
@@ -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, lp_netbios_name());
+       if (!ADS_ERR_OK(ads_status)) {
+               DEBUG(2, ("Failed to find machine account for %s\n",
+                         lp_netbios_name()));
+               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_session_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, lp_netbios_name());
-       if (!ADS_ERR_OK(ads_rc)) {
-               DEBUG(0, ("failed to find machine account for %s\n",
-                         lp_netbios_name()));
-               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;