From: Björn Jacke Date: Thu, 1 Oct 2020 19:22:28 +0000 (+0200) Subject: nt_printing_ads: support more attributes for AD published printers X-Git-Tag: talloc-2.3.2~289 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8fbda54e4d075fc49f024bc1faa95e9760386e53;p=thirdparty%2Fsamba.git nt_printing_ads: support more attributes for AD published printers BUG: https://bugzilla.samba.org/show_bug.cgi?id=9578 Signed-off-by: Bjoern Jacke Reviewed-by: Jeremy Allison Autobuild-User(master): Jeremy Allison Autobuild-Date(master): Thu Oct 8 17:52:46 UTC 2020 on sn-devel-184 --- diff --git a/source3/printing/nt_printing_ads.c b/source3/printing/nt_printing_ads.c index b3176f88b15..0ec13d1bf1a 100644 --- a/source3/printing/nt_printing_ads.c +++ b/source3/printing/nt_printing_ads.c @@ -338,6 +338,101 @@ out_ctx_free: return result; } +static WERROR nt_printer_devmode_to_mods(TALLOC_CTX *ctx, + struct spoolss_DeviceMode *devmode, + ADS_MODLIST *mods) +{ + char *str = NULL; + ADS_STATUS status; + + /* + the device mode fields bits allow us to make an educated guess if a + printer feature is supported. For sure a feature must be unsupported if + the fields bit is not set. Device Mode Extra Data and FeatureOptionPairs + might help to figure out more information here. Common attributes, that + we can't handle yet: + SPOOL_REG_PRINTBINNAMES - printBinNames + SPOOL_REG_PRINTMAXXEXTENT - printMaxXExtent + SPOOL_REG_PRINTMAXYEXTENT - printMaxYExtent + SPOOL_REG_PRINTMINXEXTENT - printMinXExtent + SPOOL_REG_PRINTMINYEXTENT - printMinYExtent + SPOOL_REG_PRINTSTAPLINGSUPPORTED - printStaplingSupported + SPOOL_REG_PRINTPAGESPERMINUTE - printPagesPerMinute + SPOOL_REG_PRINTRATE - printRate + SPOOL_REG_PRINTRATEUNIT - printRateUnit + SPOOL_REG_PRINTMEDIAREADY - printMediaReady + SPOOL_REG_PRINTMEDIASUPPORTED - printMediaSupported + SPOOL_REG_PRINTNUMBERUP - printNumberUp + SPOOL_REG_PRINTMAXCOPIES - printMaxCopies + */ + if (devmode->fields & DEVMODE_COLOR) { + status = ads_mod_str(ctx, mods, SPOOL_REG_PRINTCOLOR, "TRUE"); + } else { + status = ads_mod_str(ctx, mods, SPOOL_REG_PRINTCOLOR, "FALSE"); + } + if (!ADS_ERR_OK(status)) { + return WERR_NOT_ENOUGH_MEMORY; + } + + if (devmode->fields & DEVMODE_DUPLEX) { + status = ads_mod_str(ctx, mods, SPOOL_REG_PRINTDUPLEXSUPPORTED, "TRUE"); + } else { + status = ads_mod_str(ctx, mods, SPOOL_REG_PRINTDUPLEXSUPPORTED, "FALSE"); + } + if (!ADS_ERR_OK(status)) { + return WERR_NOT_ENOUGH_MEMORY; + } + + if (devmode->fields & DEVMODE_COLLATE) { + status = ads_mod_str(ctx, mods, SPOOL_REG_PRINTCOLLATE, "TRUE"); + } else { + status = ads_mod_str(ctx, mods, SPOOL_REG_PRINTCOLLATE, "FALSE"); + } + if (!ADS_ERR_OK(status)) { + return WERR_NOT_ENOUGH_MEMORY; + } + + /* portrait mode is always supported, LANDSCAPE is optional */ + status = ads_mod_str(ctx, mods, SPOOL_REG_PRINTORIENTATIONSSUPPORTED, "PORTRAIT"); + if (!ADS_ERR_OK(status)) { + return WERR_NOT_ENOUGH_MEMORY; + } + if (devmode->fields & DEVMODE_ORIENTATION) { + status = ads_mod_str(ctx, mods, SPOOL_REG_PRINTORIENTATIONSSUPPORTED, "LANDSCAPE"); + if (!ADS_ERR_OK(status)) { + return WERR_NOT_ENOUGH_MEMORY; + } + } + + /* the driverVersion attribute in AD contains actually specversion */ + str = talloc_asprintf(ctx, "%u", devmode->specversion); + if (str == NULL) { + return WERR_NOT_ENOUGH_MEMORY; + } + if (strlen(str) != 0) { + status = ads_mod_str(ctx, mods, SPOOL_REG_DRIVERVERSION, str); + if (!ADS_ERR_OK(status)) { + return WERR_NOT_ENOUGH_MEMORY; + } + } + + /* devmode->yresolution is a good candidate for printMaxResolutionSupported */ + str = talloc_asprintf(ctx, "%u", devmode->yresolution); + if (str == NULL) { + return WERR_NOT_ENOUGH_MEMORY; + } + if (strlen(str) != 0) { + status = ads_mod_str(ctx, mods, SPOOL_REG_PRINTMAXRESOLUTIONSUPPORTED, str); + if (!ADS_ERR_OK(status)) { + return WERR_NOT_ENOUGH_MEMORY; + } + } + + return WERR_OK; +} + + + static WERROR nt_printer_info_to_mods(TALLOC_CTX *ctx, struct spoolss_PrinterInfo2 *info2, ADS_MODLIST *mods) @@ -416,6 +511,14 @@ static WERROR nt_printer_info_to_mods(TALLOC_CTX *ctx, info2->attributes)); } + if (info2->devmode != NULL) { + WERROR werr; + werr = nt_printer_devmode_to_mods(ctx, info2->devmode, mods); + if (!W_ERROR_IS_OK(werr)) { + return werr; + } + } + return WERR_OK; }