1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-12 09:18:10 +03:00

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>
This commit is contained in:
David Disseldorp 2014-12-18 18:18:21 +01:00 committed by Günther Deschner
parent dc32f11b87
commit 7cabd89789

View 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()));
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_NOT_FOUND;
return win_rc;
}
/* 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);
TALLOC_FREE(ctx);
return WERR_SERVER_UNAVAILABLE;
}
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;