From 31c484edb95c09b0b400cff9bab6b6cb2c33b120 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 4 Aug 2010 15:31:08 +0200 Subject: s3-printing: move AD related printing components to an own file. Guenther --- source3/printing/nt_printing.c | 440 ----------------------------------------- 1 file changed, 440 deletions(-) (limited to 'source3/printing/nt_printing.c') diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c index f0460f31c2..a831ef220e 100644 --- a/source3/printing/nt_printing.c +++ b/source3/printing/nt_printing.c @@ -1312,446 +1312,6 @@ WERROR spoolss_create_default_secdesc(TALLOC_CTX *mem_ctx, return WERR_OK; } -#ifdef HAVE_ADS -/***************************************************************** - ****************************************************************/ - -static void store_printer_guid(const char *printer, struct GUID guid) -{ - TALLOC_CTX *tmp_ctx; - struct auth_serversupplied_info *server_info = NULL; - 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; - } - - status = make_server_info_system(tmp_ctx, &server_info); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0, ("store_printer_guid: " - "Could not create system server_info\n")); - goto done; - } - - guid_str = GUID_string(tmp_ctx, &guid); - if (!guid_str) { - DEBUG(0, ("store_printer_guid: Out of memory?!\n")); - goto done; - } - - /* We used to store this as a REG_BINARY but that causes - 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", - guid_str)); - goto done; - } - - result = winreg_set_printer_dataex(tmp_ctx, server_info, printer, - 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)); - } - -done: - talloc_free(tmp_ctx); -} - -static WERROR nt_printer_publish_ads(ADS_STRUCT *ads, - 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; - - /* build the ads mods */ - ctx = talloc_init("nt_printer_publish_ads"); - if (ctx == NULL) { - return WERR_NOMEM; - } - - DEBUG(5, ("publishing printer %s\n", printer)); - - /* figure out where to publish */ - ads_find_machine_acct(ads, &res, global_myname()); - - /* 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); - if (!srv_dn_utf8) { - TALLOC_FREE(ctx); - return WERR_SERVER_UNAVAILABLE; - } - ads_msgfree(ads, res); - 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) { - SAFE_FREE(prt_dn); - TALLOC_FREE(ctx); - return WERR_NOMEM; - } - - ads_mod_str(ctx, &mods, SPOOL_REG_PRINTERNAME, printer); - - /* publish it */ - ads_rc = ads_mod_printer_entry(ads, prt_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); - } - - if (!ADS_ERR_OK(ads_rc)) { - DEBUG(3, ("error publishing %s: %s\n", - printer, ads_errstr(ads_rc))); - } - - /* retreive the guid and store it locally */ - if (ADS_ERR_OK(ads_search_dn(ads, &res, prt_dn, attrs))) { - ZERO_STRUCT(guid); - ads_pull_guid(ads, res, &guid); - ads_msgfree(ads, res); - store_printer_guid(printer, guid); - } - TALLOC_FREE(ctx); - - return win_rc; -} - -static WERROR nt_printer_unpublish_ads(ADS_STRUCT *ads, - const char *printer) -{ - ADS_STATUS ads_rc; - LDAPMessage *res = NULL; - char *prt_dn = NULL; - - DEBUG(5, ("unpublishing printer %s\n", printer)); - - /* remove the printer from the directory */ - ads_rc = ads_find_printer_on_server(ads, &res, - printer, global_myname()); - - if (ADS_ERR_OK(ads_rc) && res && ads_count_replies(ads, res)) { - prt_dn = ads_get_dn(ads, talloc_tos(), res); - if (!prt_dn) { - ads_msgfree(ads, res); - return WERR_NOMEM; - } - ads_rc = ads_del_dn(ads, prt_dn); - TALLOC_FREE(prt_dn); - } - - if (res) { - ads_msgfree(ads, res); - } - return WERR_OK; -} - -/**************************************************************************** - * Publish a printer in the directory - * - * @param mem_ctx memory context - * @param server_info server_info to access winreg pipe - * @param pinfo2 printer information - * @param action publish/unpublish action - * @return WERROR indicating status of publishing - ***************************************************************************/ - -WERROR nt_printer_publish(TALLOC_CTX *mem_ctx, - struct auth_serversupplied_info *server_info, - struct spoolss_PrinterInfo2 *pinfo2, - int action) -{ - uint32_t info2_mask = SPOOLSS_PRINTER_INFO_ATTRIBUTES; - struct spoolss_SetPrinterInfo2 *sinfo2; - ADS_STATUS ads_rc; - ADS_STRUCT *ads = NULL; - WERROR win_rc; - - sinfo2 = talloc_zero(mem_ctx, struct spoolss_SetPrinterInfo2); - if (!sinfo2) { - return WERR_NOMEM; - } - - switch (action) { - case DSPRINT_PUBLISH: - case DSPRINT_UPDATE: - pinfo2->attributes |= PRINTER_ATTRIBUTE_PUBLISHED; - break; - case DSPRINT_UNPUBLISH: - pinfo2->attributes ^= PRINTER_ATTRIBUTE_PUBLISHED; - break; - default: - win_rc = WERR_NOT_SUPPORTED; - goto done; - } - - sinfo2->attributes = pinfo2->attributes; - - win_rc = winreg_update_printer(mem_ctx, server_info, - pinfo2->sharename, info2_mask, - sinfo2, NULL, NULL); - if (!W_ERROR_IS_OK(win_rc)) { - DEBUG(3, ("err %d saving data\n", W_ERROR_V(win_rc))); - goto done; - } - - TALLOC_FREE(sinfo2); - - ads = ads_init(lp_realm(), lp_workgroup(), NULL); - if (!ads) { - DEBUG(3, ("ads_init() failed\n")); - win_rc = WERR_SERVER_UNAVAILABLE; - goto done; - } - 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_connect() will find the DC for us */ - ads_rc = ads_connect(ads); - if (!ADS_ERR_OK(ads_rc)) { - DEBUG(3, ("ads_connect failed: %s\n", ads_errstr(ads_rc))); - win_rc = WERR_ACCESS_DENIED; - goto done; - } - - switch (action) { - case DSPRINT_PUBLISH: - case DSPRINT_UPDATE: - win_rc = nt_printer_publish_ads(ads, pinfo2); - break; - case DSPRINT_UNPUBLISH: - win_rc = nt_printer_unpublish_ads(ads, pinfo2->sharename); - break; - } - -done: - ads_destroy(&ads); - return win_rc; -} - -WERROR check_published_printers(void) -{ - ADS_STATUS ads_rc; - ADS_STRUCT *ads = NULL; - int snum; - int n_services = lp_numservices(); - TALLOC_CTX *tmp_ctx = NULL; - struct auth_serversupplied_info *server_info = NULL; - struct spoolss_PrinterInfo2 *pinfo2; - NTSTATUS status; - WERROR result; - - tmp_ctx = talloc_new(NULL); - if (!tmp_ctx) return WERR_NOMEM; - - ads = ads_init(lp_realm(), lp_workgroup(), NULL); - if (!ads) { - DEBUG(3, ("ads_init() failed\n")); - return WERR_SERVER_UNAVAILABLE; - } - 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_connect() will find the DC for us */ - ads_rc = ads_connect(ads); - if (!ADS_ERR_OK(ads_rc)) { - DEBUG(3, ("ads_connect failed: %s\n", ads_errstr(ads_rc))); - result = WERR_ACCESS_DENIED; - goto done; - } - - status = make_server_info_system(tmp_ctx, &server_info); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0, ("check_published_printers: " - "Could not create system server_info\n")); - result = WERR_ACCESS_DENIED; - goto done; - } - - for (snum = 0; snum < n_services; snum++) { - if (!lp_snum_ok(snum) || !lp_print_ok(snum)) { - continue; - } - - result = winreg_get_printer(tmp_ctx, server_info, NULL, - lp_servicename(snum), &pinfo2); - if (!W_ERROR_IS_OK(result)) { - continue; - } - - if (pinfo2->attributes & PRINTER_ATTRIBUTE_PUBLISHED) { - nt_printer_publish_ads(ads, pinfo2); - } - - TALLOC_FREE(pinfo2); - } - - result = WERR_OK; -done: - ads_destroy(&ads); - ads_kdestroy("MEMORY:prtpub_cache"); - talloc_free(tmp_ctx); - return result; -} - -bool is_printer_published(TALLOC_CTX *mem_ctx, - struct auth_serversupplied_info *server_info, - char *servername, char *printer, struct GUID *guid, - struct spoolss_PrinterInfo2 **info2) -{ - struct spoolss_PrinterInfo2 *pinfo2 = NULL; - enum winreg_Type type; - uint8_t *data; - uint32_t data_size; - WERROR result; - NTSTATUS status; - - result = winreg_get_printer(mem_ctx, server_info, - servername, printer, &pinfo2); - if (!W_ERROR_IS_OK(result)) { - return false; - } - - if (!(pinfo2->attributes & PRINTER_ATTRIBUTE_PUBLISHED)) { - TALLOC_FREE(pinfo2); - return false; - } - - if (!guid) { - goto done; - } - - /* fetching printer guids really ought to be a separate function. */ - - result = winreg_get_printer_dataex(mem_ctx, server_info, printer, - SPOOL_DSSPOOLER_KEY, "objectGUID", - &type, &data, &data_size); - if (!W_ERROR_IS_OK(result)) { - TALLOC_FREE(pinfo2); - return false; - } - - /* We used to store the guid as REG_BINARY, then swapped - to REG_SZ for Vista compatibility so check for both */ - - switch (type) { - case REG_SZ: - status = GUID_from_string((char *)data, guid); - if (!NT_STATUS_IS_OK(status)) { - TALLOC_FREE(pinfo2); - return false; - } - break; - - case REG_BINARY: - if (data_size != sizeof(struct GUID)) { - TALLOC_FREE(pinfo2); - return false; - } - memcpy(guid, data, sizeof(struct GUID)); - break; - default: - DEBUG(0,("is_printer_published: GUID value stored as " - "invaluid type (%d)\n", type)); - break; - } - -done: - if (info2) { - *info2 = talloc_move(mem_ctx, &pinfo2); - } - talloc_free(pinfo2); - return true; -} -#else -WERROR nt_printer_publish(TALLOC_CTX *mem_ctx, - struct auth_serversupplied_info *server_info, - struct spoolss_PrinterInfo2 *pinfo2, - int action) -{ - return WERR_OK; -} - -WERROR check_published_printers(void) -{ - return WERR_OK; -} - -bool is_printer_published(TALLOC_CTX *mem_ctx, - struct auth_serversupplied_info *server_info, - char *servername, char *printer, struct GUID *guid, - struct spoolss_PrinterInfo2 **info2) -{ - return False; -} -#endif /* HAVE_ADS */ - /**************************************************************************** ***************************************************************************/ -- cgit