LCOV - code coverage report
Current view: top level - source3/printing - nt_printing_ads.c (source / functions) Hit Total Coverage
Test: coverage report for master 98b443d9 Lines: 34 446 7.6 %
Date: 2024-05-31 13:13:24 Functions: 2 12 16.7 %

          Line data    Source code
       1             : /*
       2             :  *  Unix SMB/CIFS implementation.
       3             :  *  RPC Pipe client / server routines
       4             :  *  Copyright (C) Andrew Tridgell              1992-2000,
       5             :  *  Copyright (C) Jean François Micouleau      1998-2000.
       6             :  *  Copyright (C) Gerald Carter                2002-2005.
       7             :  *
       8             :  *  This program is free software; you can redistribute it and/or modify
       9             :  *  it under the terms of the GNU General Public License as published by
      10             :  *  the Free Software Foundation; either version 3 of the License, or
      11             :  *  (at your option) any later version.
      12             :  *
      13             :  *  This program is distributed in the hope that it will be useful,
      14             :  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      16             :  *  GNU General Public License for more details.
      17             :  *
      18             :  *  You should have received a copy of the GNU General Public License
      19             :  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
      20             :  */
      21             : 
      22             : #include "includes.h"
      23             : #include "../librpc/gen_ndr/spoolss.h"
      24             : #include "rpc_server/spoolss/srv_spoolss_util.h"
      25             : #include "nt_printing.h"
      26             : #include "ads.h"
      27             : #include "secrets.h"
      28             : #include "../libcli/registry/util_reg.h"
      29             : #include "auth.h"
      30             : #include "../librpc/ndr/libndr.h"
      31             : #include "rpc_client/cli_winreg_spoolss.h"
      32             : 
      33             : #ifdef HAVE_ADS
      34             : /*****************************************************************
      35             :  ****************************************************************/
      36             : 
      37           0 : WERROR nt_printer_guid_store(struct messaging_context *msg_ctx,
      38             :                              const char *printer, struct GUID guid)
      39             : {
      40           0 :         TALLOC_CTX *tmp_ctx;
      41           0 :         const struct auth_session_info *session_info;
      42           0 :         const char *guid_str;
      43           0 :         DATA_BLOB blob;
      44           0 :         WERROR result;
      45             : 
      46           0 :         tmp_ctx = talloc_new(NULL);
      47           0 :         if (!tmp_ctx) {
      48           0 :                 DEBUG(0, ("Out of memory?!\n"));
      49           0 :                 return WERR_NOT_ENOUGH_MEMORY;
      50             :         }
      51             : 
      52           0 :         session_info = get_session_info_system();
      53           0 :         if (session_info == NULL) {
      54           0 :                 DEBUG(0, ("Could not get system session_info\n"));
      55           0 :                 result = WERR_NOT_ENOUGH_MEMORY;
      56           0 :                 goto done;
      57             :         }
      58             : 
      59           0 :         guid_str = GUID_string(tmp_ctx, &guid);
      60           0 :         if (!guid_str) {
      61           0 :                 DEBUG(0, ("Out of memory?!\n"));
      62           0 :                 result = WERR_NOT_ENOUGH_MEMORY;
      63           0 :                 goto done;
      64             :         }
      65             : 
      66             :         /* We used to store this as a REG_BINARY but that causes
      67             :            Vista to whine */
      68             : 
      69           0 :         if (!push_reg_sz(tmp_ctx, &blob, guid_str)) {
      70           0 :                 DEBUG(0, ("Could not marshall string %s for objectGUID\n",
      71             :                           guid_str));
      72           0 :                 result = WERR_NOT_ENOUGH_MEMORY;
      73           0 :                 goto done;
      74             :         }
      75             : 
      76           0 :         result = winreg_set_printer_dataex_internal(tmp_ctx, session_info, msg_ctx,
      77             :                                            printer,
      78             :                                            SPOOL_DSSPOOLER_KEY, "objectGUID",
      79           0 :                                            REG_SZ, blob.data, blob.length);
      80           0 :         if (!W_ERROR_IS_OK(result)) {
      81           0 :                 DEBUG(0, ("Failed to store GUID for printer %s\n", printer));
      82           0 :                 goto done;
      83             :         }
      84             : 
      85           0 :         result = WERR_OK;
      86           0 : done:
      87           0 :         talloc_free(tmp_ctx);
      88             : 
      89           0 :         return result;
      90             : }
      91             : 
      92           0 : static WERROR nt_printer_dn_lookup(TALLOC_CTX *mem_ctx,
      93             :                                    ADS_STRUCT *ads,
      94             :                                    const char *printer,
      95             :                                    char **pprinter_dn)
      96             : {
      97           0 :         char *printer_dn = NULL;
      98           0 :         char *srv_dn = NULL;
      99           0 :         char *srv_cn_0 = NULL;
     100           0 :         char *srv_cn_escaped = NULL;
     101           0 :         char *sharename_escaped = NULL;
     102           0 :         char *srv_dn_utf8 = NULL;
     103           0 :         char **srv_cn_utf8 = NULL;
     104           0 :         size_t converted_size;
     105           0 :         ADS_STATUS ads_status;
     106           0 :         LDAPMessage *res;
     107           0 :         WERROR result;
     108           0 :         bool ok;
     109             : 
     110           0 :         ads_status = ads_find_machine_acct(ads, &res, lp_netbios_name());
     111           0 :         if (!ADS_ERR_OK(ads_status)) {
     112           0 :                 DEBUG(2, ("Failed to find machine account for %s\n",
     113             :                           lp_netbios_name()));
     114           0 :                 result = WERR_NOT_FOUND;
     115           0 :                 goto err_out;
     116             :         }
     117             : 
     118             :         /*
     119             :          * We use ldap_get_dn here as we need the answer in utf8 to call
     120             :          * ldap_explode_dn(). JRA.
     121             :          */
     122           0 :         srv_dn_utf8 = ldap_get_dn((LDAP *)ads->ldap.ld, (LDAPMessage *)res);
     123           0 :         ads_msgfree(ads, res);
     124           0 :         if (srv_dn_utf8 == NULL) {
     125           0 :                 result = WERR_RPC_S_SERVER_UNAVAILABLE;
     126           0 :                 goto err_out;
     127             :         }
     128             : 
     129           0 :         srv_cn_utf8 = ldap_explode_dn(srv_dn_utf8, 1);
     130           0 :         if (srv_cn_utf8 == NULL) {
     131           0 :                 ldap_memfree(srv_dn_utf8);
     132           0 :                 result = WERR_RPC_S_SERVER_UNAVAILABLE;
     133           0 :                 goto err_out;
     134             :         }
     135             : 
     136             :         /* Now convert to CH_UNIX. */
     137           0 :         ok = pull_utf8_talloc(mem_ctx, &srv_dn, srv_dn_utf8, &converted_size);
     138           0 :         ldap_memfree(srv_dn_utf8);
     139           0 :         if (!ok) {
     140           0 :                 ldap_memfree(srv_cn_utf8);
     141           0 :                 result = WERR_RPC_S_SERVER_UNAVAILABLE;
     142           0 :                 goto err_out;
     143             :         }
     144             : 
     145           0 :         ok = pull_utf8_talloc(mem_ctx, &srv_cn_0, srv_cn_utf8[0], &converted_size);
     146           0 :         ldap_memfree(srv_cn_utf8);
     147           0 :         if (!ok) {
     148           0 :                 result = WERR_RPC_S_SERVER_UNAVAILABLE;
     149           0 :                 goto err_out;
     150             :         }
     151             : 
     152           0 :         srv_cn_escaped = escape_rdn_val_string_alloc(srv_cn_0);
     153           0 :         if (srv_cn_escaped == NULL) {
     154           0 :                 result = WERR_RPC_S_SERVER_UNAVAILABLE;
     155           0 :                 goto err_out;
     156             :         }
     157             : 
     158           0 :         sharename_escaped = escape_rdn_val_string_alloc(printer);
     159           0 :         if (sharename_escaped == NULL) {
     160           0 :                 result = WERR_RPC_S_SERVER_UNAVAILABLE;
     161           0 :                 goto err_out;
     162             :         }
     163             : 
     164           0 :         printer_dn = talloc_asprintf(mem_ctx,
     165             :                                      "cn=%s-%s,%s",
     166             :                                      srv_cn_escaped,
     167             :                                      sharename_escaped,
     168             :                                      srv_dn);
     169           0 :         if (printer_dn == NULL) {
     170           0 :                 result = WERR_NOT_ENOUGH_MEMORY;
     171           0 :                 goto err_out;
     172             :         }
     173             : 
     174           0 :         *pprinter_dn = printer_dn;
     175             : 
     176           0 :         result = WERR_OK;
     177           0 : err_out:
     178           0 :         SAFE_FREE(sharename_escaped);
     179           0 :         SAFE_FREE(srv_cn_escaped);
     180           0 :         TALLOC_FREE(srv_cn_0);
     181           0 :         TALLOC_FREE(srv_dn);
     182           0 :         return result;
     183             : }
     184             : 
     185           0 : static WERROR nt_printer_guid_retrieve_internal(ADS_STRUCT *ads,
     186             :                                                 const char *printer_dn,
     187             :                                                 struct GUID *pguid)
     188             : {
     189           0 :         ADS_STATUS ads_status;
     190           0 :         LDAPMessage *res;
     191           0 :         const char *attrs[] = {"objectGUID", NULL};
     192           0 :         struct GUID guid;
     193           0 :         bool ok;
     194             : 
     195           0 :         ads_status = ads_search_dn(ads, &res, printer_dn, attrs);
     196           0 :         if (!ADS_ERR_OK(ads_status)) {
     197           0 :                 DEBUG(2, ("Failed to retrieve GUID from DC - %s\n",
     198             :                           ads_errstr(ads_status)));
     199           0 :                 return WERR_FILE_NOT_FOUND;
     200             :         }
     201             : 
     202           0 :         ZERO_STRUCT(guid);
     203           0 :         ok = ads_pull_guid(ads, res, &guid);
     204           0 :         ads_msgfree(ads, res);
     205           0 :         if (!ok) {
     206           0 :                 return WERR_NOT_ENOUGH_MEMORY;
     207             :         }
     208             : 
     209           0 :         *pguid = guid;
     210             : 
     211           0 :         return WERR_OK;
     212             : }
     213             : 
     214           0 : WERROR nt_printer_guid_retrieve(TALLOC_CTX *mem_ctx, const char *printer,
     215             :                                 struct GUID *pguid)
     216             : {
     217           0 :         ADS_STRUCT *ads = NULL;
     218           0 :         char *printer_dn;
     219           0 :         WERROR result;
     220           0 :         ADS_STATUS ads_status;
     221           0 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
     222             : 
     223           0 :         ads = ads_init(tmp_ctx,
     224             :                        lp_realm(),
     225             :                        lp_workgroup(),
     226             :                        NULL,
     227             :                        ADS_SASL_PLAIN);
     228           0 :         if (ads == NULL) {
     229           0 :                 result = WERR_RPC_S_SERVER_UNAVAILABLE;
     230           0 :                 goto out;
     231             :         }
     232             : 
     233           0 :         ads_status = ads_connect_machine(ads);
     234           0 :         if (!ADS_ERR_OK(ads_status)) {
     235           0 :                 DEBUG(3, ("ads_connect_machine failed: %s\n", ads_errstr(ads_status)));
     236           0 :                 result = WERR_ACCESS_DENIED;
     237           0 :                 goto out;
     238             :         }
     239             : 
     240           0 :         result = nt_printer_dn_lookup(tmp_ctx, ads, printer, &printer_dn);
     241           0 :         if (!W_ERROR_IS_OK(result)) {
     242           0 :                 goto out;
     243             :         }
     244             : 
     245           0 :         result = nt_printer_guid_retrieve_internal(ads, printer_dn, pguid);
     246           0 : out:
     247           0 :         TALLOC_FREE(tmp_ctx);
     248             : 
     249           0 :         return result;
     250             : }
     251             : 
     252           0 : WERROR nt_printer_guid_get(TALLOC_CTX *mem_ctx,
     253             :                            const struct auth_session_info *session_info,
     254             :                            struct messaging_context *msg_ctx,
     255             :                            const char *printer, struct GUID *guid)
     256             : {
     257           0 :         TALLOC_CTX *tmp_ctx;
     258           0 :         enum winreg_Type type;
     259           0 :         DATA_BLOB blob;
     260           0 :         uint32_t len;
     261           0 :         NTSTATUS status;
     262           0 :         WERROR result;
     263             : 
     264           0 :         tmp_ctx = talloc_new(mem_ctx);
     265           0 :         if (tmp_ctx == NULL) {
     266           0 :                 DEBUG(0, ("out of memory?!\n"));
     267           0 :                 return WERR_NOT_ENOUGH_MEMORY;
     268             :         }
     269             : 
     270           0 :         result = winreg_get_printer_dataex_internal(tmp_ctx, session_info,
     271             :                                                     msg_ctx, printer,
     272             :                                                     SPOOL_DSSPOOLER_KEY,
     273             :                                                     "objectGUID",
     274             :                                                     &type,
     275             :                                                     &blob.data,
     276             :                                                     &len);
     277           0 :         if (!W_ERROR_IS_OK(result)) {
     278           0 :                 DEBUG(0, ("Failed to get GUID for printer %s\n", printer));
     279           0 :                 goto out_ctx_free;
     280             :         }
     281           0 :         blob.length = (size_t)len;
     282             : 
     283             :         /* We used to store the guid as REG_BINARY, then swapped
     284             :            to REG_SZ for Vista compatibility so check for both */
     285             : 
     286           0 :         switch (type) {
     287           0 :         case REG_SZ: {
     288           0 :                 bool ok;
     289           0 :                 const char *guid_str;
     290           0 :                 ok = pull_reg_sz(tmp_ctx, &blob, &guid_str);
     291           0 :                 if (!ok) {
     292           0 :                         DEBUG(0, ("Failed to unmarshall GUID for printer %s\n",
     293             :                                   printer));
     294           0 :                         result = WERR_REGISTRY_CORRUPT;
     295           0 :                         goto out_ctx_free;
     296             :                 }
     297           0 :                 status = GUID_from_string(guid_str, guid);
     298           0 :                 if (!NT_STATUS_IS_OK(status)) {
     299           0 :                         DEBUG(0, ("bad GUID for printer %s\n", printer));
     300           0 :                         result = ntstatus_to_werror(status);
     301           0 :                         goto out_ctx_free;
     302             :                 }
     303           0 :                 break;
     304             :         }
     305           0 :         case REG_BINARY:
     306           0 :                 if (blob.length != sizeof(struct GUID)) {
     307           0 :                         DEBUG(0, ("bad GUID for printer %s\n", printer));
     308           0 :                         result = WERR_REGISTRY_CORRUPT;
     309           0 :                         goto out_ctx_free;
     310             :                 }
     311           0 :                 memcpy(guid, blob.data, sizeof(struct GUID));
     312           0 :                 break;
     313           0 :         default:
     314           0 :                 DEBUG(0,("GUID value stored as invalid type (%d)\n", type));
     315           0 :                 result = WERR_REGISTRY_CORRUPT;
     316           0 :                 goto out_ctx_free;
     317             :                 break;
     318             :         }
     319           0 :         result = WERR_OK;
     320             : 
     321           0 : out_ctx_free:
     322           0 :         talloc_free(tmp_ctx);
     323           0 :         return result;
     324             : }
     325             : 
     326           0 : static WERROR nt_printer_devmode_to_mods(TALLOC_CTX *ctx,
     327             :                                         struct spoolss_DeviceMode *devmode,
     328             :                                         ADS_MODLIST *mods)
     329             : {
     330           0 :         char *str = NULL;
     331           0 :         ADS_STATUS status;
     332             : 
     333             :         /*
     334             :            the device mode fields bits allow us to make an educated guess if a
     335             :            printer feature is supported. For sure a feature must be unsupported if
     336             :            the fields bit is not set. Device Mode Extra Data and FeatureOptionPairs
     337             :            might help to figure out more information here. Common attributes, that
     338             :            we can't handle yet:
     339             :                 SPOOL_REG_PRINTBINNAMES - printBinNames
     340             :                 SPOOL_REG_PRINTMAXXEXTENT - printMaxXExtent
     341             :                 SPOOL_REG_PRINTMAXYEXTENT - printMaxYExtent
     342             :                 SPOOL_REG_PRINTMINXEXTENT - printMinXExtent
     343             :                 SPOOL_REG_PRINTMINYEXTENT - printMinYExtent
     344             :                 SPOOL_REG_PRINTSTAPLINGSUPPORTED - printStaplingSupported
     345             :                 SPOOL_REG_PRINTPAGESPERMINUTE - printPagesPerMinute
     346             :                 SPOOL_REG_PRINTRATE - printRate
     347             :                 SPOOL_REG_PRINTRATEUNIT - printRateUnit
     348             :                 SPOOL_REG_PRINTMEDIAREADY - printMediaReady
     349             :                 SPOOL_REG_PRINTMEDIASUPPORTED - printMediaSupported
     350             :                 SPOOL_REG_PRINTNUMBERUP - printNumberUp
     351             :                 SPOOL_REG_PRINTMAXCOPIES - printMaxCopies
     352             :         */
     353           0 :         if (devmode->fields & DEVMODE_COLOR) {
     354           0 :                 status = ads_mod_str(ctx, mods, SPOOL_REG_PRINTCOLOR, "TRUE");
     355             :         } else {
     356           0 :                 status = ads_mod_str(ctx, mods, SPOOL_REG_PRINTCOLOR, "FALSE");
     357             :         }
     358           0 :         if (!ADS_ERR_OK(status)) {
     359           0 :                 return WERR_NOT_ENOUGH_MEMORY;
     360             :         }
     361             : 
     362           0 :         if (devmode->fields & DEVMODE_DUPLEX) {
     363           0 :                 status = ads_mod_str(ctx, mods, SPOOL_REG_PRINTDUPLEXSUPPORTED, "TRUE");
     364             :         } else {
     365           0 :                 status = ads_mod_str(ctx, mods, SPOOL_REG_PRINTDUPLEXSUPPORTED, "FALSE");
     366             :         }
     367           0 :         if (!ADS_ERR_OK(status)) {
     368           0 :                 return WERR_NOT_ENOUGH_MEMORY;
     369             :         }
     370             : 
     371           0 :         if (devmode->fields & DEVMODE_COLLATE) {
     372           0 :                 status = ads_mod_str(ctx, mods, SPOOL_REG_PRINTCOLLATE, "TRUE");
     373             :         } else {
     374           0 :                 status = ads_mod_str(ctx, mods, SPOOL_REG_PRINTCOLLATE, "FALSE");
     375             :         }
     376           0 :         if (!ADS_ERR_OK(status)) {
     377           0 :                 return WERR_NOT_ENOUGH_MEMORY;
     378             :         }
     379             : 
     380             :         /* portrait mode is always supported, LANDSCAPE is optional */
     381           0 :         status = ads_mod_str(ctx, mods, SPOOL_REG_PRINTORIENTATIONSSUPPORTED, "PORTRAIT");
     382           0 :         if (!ADS_ERR_OK(status)) {
     383           0 :                 return WERR_NOT_ENOUGH_MEMORY;
     384             :         }
     385           0 :         if (devmode->fields & DEVMODE_ORIENTATION) {
     386           0 :                 status = ads_mod_str(ctx, mods, SPOOL_REG_PRINTORIENTATIONSSUPPORTED, "LANDSCAPE");
     387           0 :                 if (!ADS_ERR_OK(status)) {
     388           0 :                         return WERR_NOT_ENOUGH_MEMORY;
     389             :                 }
     390             :         }
     391             : 
     392             :         /* the driverVersion attribute in AD contains actually specversion */
     393           0 :         str = talloc_asprintf(ctx, "%u", devmode->specversion);
     394           0 :         if (str == NULL) {
     395           0 :                 return WERR_NOT_ENOUGH_MEMORY;
     396             :         }
     397           0 :         if (strlen(str) != 0) {
     398           0 :                 status = ads_mod_str(ctx, mods, SPOOL_REG_DRIVERVERSION, str);
     399           0 :                 if (!ADS_ERR_OK(status)) {
     400           0 :                         return WERR_NOT_ENOUGH_MEMORY;
     401             :                 }
     402             :         }
     403             : 
     404             :         /* devmode->yresolution is a good candidate for printMaxResolutionSupported */
     405           0 :         str = talloc_asprintf(ctx, "%u", devmode->yresolution);
     406           0 :         if (str == NULL) {
     407           0 :                 return WERR_NOT_ENOUGH_MEMORY;
     408             :         }
     409           0 :         if (strlen(str) != 0) {
     410           0 :                 status = ads_mod_str(ctx, mods, SPOOL_REG_PRINTMAXRESOLUTIONSUPPORTED, str);
     411           0 :                 if (!ADS_ERR_OK(status)) {
     412           0 :                         return WERR_NOT_ENOUGH_MEMORY;
     413             :                 }
     414             :         }
     415             : 
     416           0 :         return WERR_OK;
     417             : }
     418             : 
     419             : 
     420             : 
     421           0 : static WERROR nt_printer_info_to_mods(TALLOC_CTX *ctx,
     422             :                                       struct spoolss_PrinterInfo2 *info2,
     423             :                                       ADS_MODLIST *mods)
     424             : {
     425           0 :         char *info_str;
     426             : 
     427           0 :         ads_mod_str(ctx, mods, SPOOL_REG_PRINTERNAME, info2->sharename);
     428           0 :         ads_mod_str(ctx, mods, SPOOL_REG_PRINTSHARENAME, info2->sharename);
     429           0 :         ads_mod_str(ctx, mods, SPOOL_REG_SHORTSERVERNAME, lp_netbios_name());
     430           0 :         ads_mod_str(ctx, mods, SPOOL_REG_SERVERNAME, get_mydnsfullname());
     431             : 
     432           0 :         info_str = talloc_asprintf(ctx, "\\\\%s\\%s",
     433             :                                    get_mydnsfullname(), info2->sharename);
     434           0 :         if (info_str == NULL) {
     435           0 :                 return WERR_NOT_ENOUGH_MEMORY;
     436             :         }
     437           0 :         ads_mod_str(ctx, mods, SPOOL_REG_UNCNAME, info_str);
     438             : 
     439           0 :         info_str = talloc_asprintf(ctx, "%d", 4);
     440           0 :         if (info_str == NULL) {
     441           0 :                 return WERR_NOT_ENOUGH_MEMORY;
     442             :         }
     443           0 :         ads_mod_str(ctx, mods, SPOOL_REG_VERSIONNUMBER, info_str);
     444             : 
     445             :         /* empty strings in the mods list result in an attribute error */
     446           0 :         if (strlen(info2->drivername) != 0)
     447           0 :                 ads_mod_str(ctx, mods, SPOOL_REG_DRIVERNAME, info2->drivername);
     448           0 :         if (strlen(info2->location) != 0)
     449           0 :                 ads_mod_str(ctx, mods, SPOOL_REG_LOCATION, info2->location);
     450           0 :         if (strlen(info2->comment) != 0)
     451           0 :                 ads_mod_str(ctx, mods, SPOOL_REG_DESCRIPTION, info2->comment);
     452           0 :         if (strlen(info2->portname) != 0)
     453           0 :                 ads_mod_str(ctx, mods, SPOOL_REG_PORTNAME, info2->portname);
     454           0 :         if (strlen(info2->sepfile) != 0)
     455           0 :                 ads_mod_str(ctx, mods, SPOOL_REG_PRINTSEPARATORFILE, info2->sepfile);
     456             : 
     457           0 :         info_str = talloc_asprintf(ctx, "%u", info2->starttime);
     458           0 :         if (info_str == NULL) {
     459           0 :                 return WERR_NOT_ENOUGH_MEMORY;
     460             :         }
     461           0 :         ads_mod_str(ctx, mods, SPOOL_REG_PRINTSTARTTIME, info_str);
     462             : 
     463           0 :         info_str = talloc_asprintf(ctx, "%u", info2->untiltime);
     464           0 :         if (info_str == NULL) {
     465           0 :                 return WERR_NOT_ENOUGH_MEMORY;
     466             :         }
     467           0 :         ads_mod_str(ctx, mods, SPOOL_REG_PRINTENDTIME, info_str);
     468             : 
     469           0 :         info_str = talloc_asprintf(ctx, "%u", info2->priority);
     470           0 :         if (info_str == NULL) {
     471           0 :                 return WERR_NOT_ENOUGH_MEMORY;
     472             :         }
     473           0 :         ads_mod_str(ctx, mods, SPOOL_REG_PRIORITY, info_str);
     474             : 
     475           0 :         if (info2->attributes & PRINTER_ATTRIBUTE_KEEPPRINTEDJOBS) {
     476           0 :                 ads_mod_str(ctx, mods, SPOOL_REG_PRINTKEEPPRINTEDJOBS, "TRUE");
     477             :         } else {
     478           0 :                 ads_mod_str(ctx, mods, SPOOL_REG_PRINTKEEPPRINTEDJOBS, "FALSE");
     479             :         }
     480             : 
     481           0 :         switch (info2->attributes & 0x3) {
     482           0 :         case 0:
     483           0 :                 ads_mod_str(ctx, mods, SPOOL_REG_PRINTSPOOLING,
     484             :                             SPOOL_REGVAL_PRINTWHILESPOOLING);
     485           0 :                 break;
     486           0 :         case 1:
     487           0 :                 ads_mod_str(ctx, mods, SPOOL_REG_PRINTSPOOLING,
     488             :                             SPOOL_REGVAL_PRINTAFTERSPOOLED);
     489           0 :                 break;
     490           0 :         case 2:
     491           0 :                 ads_mod_str(ctx, mods, SPOOL_REG_PRINTSPOOLING,
     492             :                             SPOOL_REGVAL_PRINTDIRECT);
     493           0 :                 break;
     494           0 :         default:
     495           0 :                 DEBUG(3, ("unsupported printer attributes %x\n",
     496             :                           info2->attributes));
     497             :         }
     498             : 
     499           0 :         if (info2->devmode != NULL) {
     500           0 :                 WERROR werr;
     501           0 :                 werr = nt_printer_devmode_to_mods(ctx, info2->devmode, mods);
     502           0 :                 if (!W_ERROR_IS_OK(werr)) {
     503           0 :                         return werr;
     504             :                 }
     505             :         }
     506             : 
     507           0 :         return WERR_OK;
     508             : }
     509             : 
     510           0 : static WERROR nt_printer_publish_ads(struct messaging_context *msg_ctx,
     511             :                                      ADS_STRUCT *ads,
     512             :                                      struct spoolss_PrinterInfo2 *pinfo2)
     513             : {
     514           0 :         ADS_STATUS ads_rc;
     515           0 :         TALLOC_CTX *ctx = talloc_stackframe();
     516           0 :         ADS_MODLIST mods;
     517           0 :         struct GUID guid;
     518           0 :         WERROR win_rc = WERR_OK;
     519           0 :         const char *printer = pinfo2->sharename;
     520           0 :         char *printer_dn = NULL;
     521             : 
     522             :         /* build the ads mods */
     523           0 :         DEBUG(5, ("publishing printer %s\n", printer));
     524             : 
     525           0 :         win_rc = nt_printer_dn_lookup(ctx, ads, printer, &printer_dn);
     526           0 :         if (!W_ERROR_IS_OK(win_rc)) {
     527           0 :                 DEBUG(2, ("Failed to create printer dn\n"));
     528           0 :                 TALLOC_FREE(ctx);
     529           0 :                 return win_rc;
     530             :         }
     531             : 
     532           0 :         mods = ads_init_mods(ctx);
     533             : 
     534           0 :         if (mods == NULL) {
     535           0 :                 TALLOC_FREE(ctx);
     536           0 :                 return WERR_NOT_ENOUGH_MEMORY;
     537             :         }
     538             : 
     539           0 :         win_rc = nt_printer_info_to_mods(ctx, pinfo2, &mods);
     540           0 :         if (!W_ERROR_IS_OK(win_rc)) {
     541           0 :                 TALLOC_FREE(ctx);
     542           0 :                 return win_rc;
     543             :         }
     544             : 
     545             :         /* publish it */
     546           0 :         ads_rc = ads_mod_printer_entry(ads, printer_dn, ctx, &mods);
     547           0 :         if (ads_rc.err.rc == LDAP_NO_SUCH_OBJECT) {
     548             :                 int i;
     549           0 :                 for (i=0; mods[i] != 0; i++)
     550             :                         ;
     551           0 :                 mods[i] = (LDAPMod *)-1;
     552           0 :                 ads_rc = ads_add_printer_entry(ads, printer_dn, ctx, &mods);
     553             :         }
     554             : 
     555           0 :         if (!ADS_ERR_OK(ads_rc)) {
     556           0 :                 DEBUG(3, ("error publishing %s: %s\n",
     557             :                           printer, ads_errstr(ads_rc)));
     558             :                 /* XXX failed to publish, so no guid to retrieve */
     559             :         }
     560             : 
     561           0 :         win_rc = nt_printer_guid_retrieve_internal(ads, printer_dn, &guid);
     562           0 :         if (!W_ERROR_IS_OK(win_rc)) {
     563           0 :                 TALLOC_FREE(ctx);
     564           0 :                 return win_rc;
     565             :         }
     566             : 
     567           0 :         win_rc = nt_printer_guid_store(msg_ctx, printer, guid);
     568           0 :         if (!W_ERROR_IS_OK(win_rc)) {
     569           0 :                 DEBUG(3, ("failed to store printer %s guid\n",
     570             :                           printer));
     571             :                 /* not catastrophic, retrieve on next use */
     572           0 :                 win_rc = WERR_OK;
     573             :         }
     574             : 
     575           0 :         TALLOC_FREE(ctx);
     576             : 
     577           0 :         return win_rc;
     578             : }
     579             : 
     580           0 : static WERROR nt_printer_unpublish_ads(ADS_STRUCT *ads,
     581             :                                        const char *printer)
     582             : {
     583           0 :         ADS_STATUS ads_rc;
     584           0 :         LDAPMessage *res = NULL;
     585           0 :         char *prt_dn = NULL;
     586             : 
     587           0 :         DEBUG(5, ("unpublishing printer %s\n", printer));
     588             : 
     589             :         /* remove the printer from the directory */
     590           0 :         ads_rc = ads_find_printer_on_server(ads, &res,
     591             :                                             printer, lp_netbios_name());
     592             : 
     593           0 :         if (ADS_ERR_OK(ads_rc) && res && ads_count_replies(ads, res)) {
     594           0 :                 prt_dn = ads_get_dn(ads, talloc_tos(), res);
     595           0 :                 if (!prt_dn) {
     596           0 :                         ads_msgfree(ads, res);
     597           0 :                         return WERR_NOT_ENOUGH_MEMORY;
     598             :                 }
     599           0 :                 ads_rc = ads_del_dn(ads, prt_dn);
     600           0 :                 TALLOC_FREE(prt_dn);
     601             :         }
     602             : 
     603           0 :         if (res) {
     604           0 :                 ads_msgfree(ads, res);
     605             :         }
     606           0 :         return WERR_OK;
     607             : }
     608             : 
     609             : /****************************************************************************
     610             :  * Publish a printer in the directory
     611             :  *
     612             :  * @param mem_ctx      memory context
     613             :  * @param session_info  session_info to access winreg pipe
     614             :  * @param pinfo2       printer information
     615             :  * @param action       publish/unpublish action
     616             :  * @return WERROR indicating status of publishing
     617             :  ***************************************************************************/
     618             : 
     619           0 : WERROR nt_printer_publish(TALLOC_CTX *mem_ctx,
     620             :                           const struct auth_session_info *session_info,
     621             :                           struct messaging_context *msg_ctx,
     622             :                           struct spoolss_PrinterInfo2 *pinfo2,
     623             :                           int action)
     624             : {
     625           0 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
     626           0 :         uint32_t info2_mask = SPOOLSS_PRINTER_INFO_ATTRIBUTES;
     627           0 :         struct spoolss_SetPrinterInfo2 *sinfo2;
     628           0 :         ADS_STATUS ads_rc;
     629           0 :         ADS_STRUCT *ads = NULL;
     630           0 :         WERROR win_rc;
     631             : 
     632           0 :         sinfo2 = talloc_zero(tmp_ctx, struct spoolss_SetPrinterInfo2);
     633           0 :         if (!sinfo2) {
     634           0 :                 win_rc = WERR_NOT_ENOUGH_MEMORY;
     635           0 :                 goto done;
     636             :         }
     637             : 
     638           0 :         switch (action) {
     639           0 :         case DSPRINT_PUBLISH:
     640             :         case DSPRINT_UPDATE:
     641           0 :                 pinfo2->attributes |= PRINTER_ATTRIBUTE_PUBLISHED;
     642           0 :                 break;
     643           0 :         case DSPRINT_UNPUBLISH:
     644           0 :                 pinfo2->attributes &= (~PRINTER_ATTRIBUTE_PUBLISHED);
     645           0 :                 break;
     646           0 :         default:
     647           0 :                 win_rc = WERR_NOT_SUPPORTED;
     648           0 :                 goto done;
     649             :         }
     650             : 
     651           0 :         sinfo2->attributes = pinfo2->attributes;
     652             : 
     653           0 :         win_rc = winreg_update_printer_internal(tmp_ctx, session_info, msg_ctx,
     654             :                                         pinfo2->sharename, info2_mask,
     655             :                                         sinfo2, NULL, NULL);
     656           0 :         if (!W_ERROR_IS_OK(win_rc)) {
     657           0 :                 DBG_NOTICE("Failed to update data for printer [%s] - %s\n",
     658             :                            pinfo2->sharename,
     659             :                            win_errstr(win_rc));
     660           0 :                 goto done;
     661             :         }
     662             : 
     663           0 :         TALLOC_FREE(sinfo2);
     664             : 
     665           0 :         ads = ads_init(tmp_ctx,
     666             :                        lp_realm(),
     667             :                        lp_workgroup(),
     668             :                        NULL,
     669             :                        ADS_SASL_PLAIN);
     670           0 :         if (!ads) {
     671           0 :                 DEBUG(3, ("ads_init() failed\n"));
     672           0 :                 win_rc = WERR_RPC_S_SERVER_UNAVAILABLE;
     673           0 :                 goto done;
     674             :         }
     675             : 
     676             :         /* ads_connect_machine() will find the DC for us */
     677           0 :         ads_rc = ads_connect_machine(ads);
     678           0 :         if (!ADS_ERR_OK(ads_rc)) {
     679           0 :                 DEBUG(3, ("ads_connect_machine failed: %s\n", ads_errstr(ads_rc)));
     680           0 :                 win_rc = WERR_ACCESS_DENIED;
     681           0 :                 goto done;
     682             :         }
     683             : 
     684           0 :         switch (action) {
     685           0 :         case DSPRINT_PUBLISH:
     686             :         case DSPRINT_UPDATE:
     687           0 :                 win_rc = nt_printer_publish_ads(msg_ctx, ads, pinfo2);
     688           0 :                 break;
     689           0 :         case DSPRINT_UNPUBLISH:
     690           0 :                 win_rc = nt_printer_unpublish_ads(ads, pinfo2->sharename);
     691           0 :                 break;
     692             :         }
     693             : 
     694           0 : done:
     695           0 :         TALLOC_FREE(tmp_ctx);
     696             : 
     697           0 :         return win_rc;
     698             : }
     699             : 
     700           2 : WERROR check_published_printers(struct messaging_context *msg_ctx)
     701             : {
     702           0 :         const struct loadparm_substitution *lp_sub =
     703           2 :                 loadparm_s3_global_substitution();
     704           0 :         ADS_STATUS ads_rc;
     705           2 :         ADS_STRUCT *ads = NULL;
     706           0 :         int snum;
     707           2 :         int n_services = lp_numservices();
     708           2 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
     709           2 :         struct auth_session_info *session_info = NULL;
     710           0 :         struct spoolss_PrinterInfo2 *pinfo2;
     711           0 :         NTSTATUS status;
     712           0 :         WERROR result;
     713             : 
     714           2 :         ads = ads_init(tmp_ctx,
     715             :                        lp_realm(),
     716             :                        lp_workgroup(),
     717             :                        NULL,
     718             :                        ADS_SASL_PLAIN);
     719           2 :         if (!ads) {
     720           0 :                 DEBUG(3, ("ads_init() failed\n"));
     721           0 :                 TALLOC_FREE(tmp_ctx);
     722           0 :                 return WERR_RPC_S_SERVER_UNAVAILABLE;
     723             :         }
     724             : 
     725             :         /* ads_connect_machine() will find the DC for us */
     726           2 :         ads_rc = ads_connect_machine(ads);
     727           2 :         if (!ADS_ERR_OK(ads_rc)) {
     728           0 :                 DEBUG(3, ("ads_connect_machine failed: %s\n", ads_errstr(ads_rc)));
     729           0 :                 result = WERR_ACCESS_DENIED;
     730           0 :                 goto done;
     731             :         }
     732             : 
     733           2 :         status = make_session_info_system(tmp_ctx, &session_info);
     734           2 :         if (!NT_STATUS_IS_OK(status)) {
     735           0 :                 DEBUG(0, ("check_published_printers: "
     736             :                           "Could not create system session_info\n"));
     737           0 :                 result = WERR_ACCESS_DENIED;
     738           0 :                 goto done;
     739             :         }
     740             : 
     741         246 :         for (snum = 0; snum < n_services; snum++) {
     742         244 :                 if (!lp_snum_ok(snum) || !lp_printable(snum)) {
     743         234 :                         continue;
     744             :                 }
     745             : 
     746          10 :                 result = winreg_get_printer_internal(tmp_ctx, session_info, msg_ctx,
     747          10 :                                             lp_servicename(talloc_tos(), lp_sub, snum),
     748             :                                             &pinfo2);
     749          10 :                 if (!W_ERROR_IS_OK(result)) {
     750          10 :                         continue;
     751             :                 }
     752             : 
     753           0 :                 if (pinfo2->attributes & PRINTER_ATTRIBUTE_PUBLISHED) {
     754           0 :                         nt_printer_publish_ads(msg_ctx, ads, pinfo2);
     755             :                 }
     756             : 
     757           0 :                 TALLOC_FREE(pinfo2);
     758             :         }
     759             : 
     760           2 :         result = WERR_OK;
     761           2 : done:
     762           2 :         talloc_free(tmp_ctx);
     763           2 :         return result;
     764             : }
     765             : 
     766          84 : bool is_printer_published(TALLOC_CTX *mem_ctx,
     767             :                           const struct auth_session_info *session_info,
     768             :                           struct messaging_context *msg_ctx,
     769             :                           const char *servername,
     770             :                           const char *printer,
     771             :                           struct spoolss_PrinterInfo2 **info2)
     772             : {
     773          84 :         struct spoolss_PrinterInfo2 *pinfo2 = NULL;
     774           0 :         WERROR result;
     775           0 :         struct dcerpc_binding_handle *b;
     776             : 
     777          84 :         result = winreg_printer_binding_handle(mem_ctx,
     778             :                                                session_info,
     779             :                                                msg_ctx,
     780             :                                                &b);
     781          84 :         if (!W_ERROR_IS_OK(result)) {
     782           0 :                 return false;
     783             :         }
     784             : 
     785          84 :         result = winreg_get_printer(mem_ctx, b,
     786             :                                     printer, &pinfo2);
     787          84 :         if (!W_ERROR_IS_OK(result)) {
     788           0 :                 return false;
     789             :         }
     790             : 
     791          84 :         if (!(pinfo2->attributes & PRINTER_ATTRIBUTE_PUBLISHED)) {
     792          84 :                 TALLOC_FREE(pinfo2);
     793          84 :                 return false;
     794             :         }
     795             : 
     796           0 :         if (info2) {
     797           0 :                 *info2 = talloc_move(mem_ctx, &pinfo2);
     798             :         }
     799           0 :         talloc_free(pinfo2);
     800           0 :         return true;
     801             : }
     802             : #else
     803           0 : WERROR nt_printer_guid_store(struct messaging_context *msg_ctx,
     804             :                            const char *printer, struct GUID guid)
     805             : {
     806           0 :         return WERR_NOT_SUPPORTED;
     807             : }
     808             : 
     809           0 : WERROR nt_printer_guid_retrieve(TALLOC_CTX *mem_ctx, const char *printer,
     810             :                                 struct GUID *pguid)
     811             : {
     812           0 :         return WERR_NOT_SUPPORTED;
     813             : }
     814             : 
     815           0 : WERROR nt_printer_guid_get(TALLOC_CTX *mem_ctx,
     816             :                            const struct auth_session_info *session_info,
     817             :                            struct messaging_context *msg_ctx,
     818             :                            const char *printer, struct GUID *guid)
     819             : {
     820           0 :         return WERR_NOT_SUPPORTED;
     821             : }
     822             : 
     823           0 : WERROR nt_printer_publish(TALLOC_CTX *mem_ctx,
     824             :                           const struct auth_session_info *session_info,
     825             :                           struct messaging_context *msg_ctx,
     826             :                           struct spoolss_PrinterInfo2 *pinfo2,
     827             :                           int action)
     828             : {
     829           0 :         return WERR_OK;
     830             : }
     831             : 
     832           0 : WERROR check_published_printers(struct messaging_context *msg_ctx)
     833             : {
     834           0 :         return WERR_OK;
     835             : }
     836             : 
     837          28 : bool is_printer_published(TALLOC_CTX *mem_ctx,
     838             :                           const struct auth_session_info *session_info,
     839             :                           struct messaging_context *msg_ctx,
     840             :                           const char *servername,
     841             :                           const char *printer,
     842             :                           struct spoolss_PrinterInfo2 **info2)
     843             : {
     844          28 :         return False;
     845             : }
     846             : #endif /* HAVE_ADS */

Generated by: LCOV version 1.14