From 7cabd89789a50d37fc32735968c493092a37e69f Mon Sep 17 00:00:00 2001 From: David Disseldorp Date: Thu, 18 Dec 2014 18:18:21 +0100 Subject: [PATCH] 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 Signed-off-by: David Disseldorp Signed-off-by: Andreas Schneider Reviewed-by: Guenther Deschner --- 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 5a5a17751d84..c136a70c034d 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, 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; -- 2.34.1