2010-03-15 14:24:40 +03:00
/*
* Unix SMB / CIFS implementation .
*
* SPOOLSS RPC Pipe server / winreg client routines
*
* Copyright ( c ) 2010 Andreas Schneider < asn @ samba . org >
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation ; either version 3 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not , see < http : //www.gnu.org/licenses/>.
*/
# include "includes.h"
# include "srv_spoolss_util.h"
# include "../librpc/gen_ndr/srv_winreg.h"
# include "../librpc/gen_ndr/cli_winreg.h"
2010-03-30 16:46:32 +04:00
# define TOP_LEVEL_PRINT_KEY "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Print"
# define TOP_LEVEL_PRINT_PRINTERS_KEY TOP_LEVEL_PRINT_KEY "\\Printers"
# define TOP_LEVEL_CONTROL_KEY "SYSTEM\\CurrentControlSet\\Control\\Print"
# define TOP_LEVEL_CONTROL_FORMS_KEY TOP_LEVEL_CONTROL_KEY "\\Forms"
2010-04-21 19:13:02 +04:00
# define EMPTY_STRING ""
# define CHECK_ERROR(result) \
if ( W_ERROR_IS_OK ( result ) ) continue ; \
if ( W_ERROR_EQUAL ( result , WERR_NOT_FOUND ) ) result = WERR_OK ; \
if ( ! W_ERROR_IS_OK ( result ) ) break
2010-03-31 15:03:09 +04:00
/* FLAGS, NAME, with, height, left, top, right, bottom */
static const struct spoolss_FormInfo1 builtin_forms1 [ ] = {
{ SPOOLSS_FORM_BUILTIN , " Letter " , { 0x34b5c , 0x44368 } , { 0x0 , 0x0 , 0x34b5c , 0x44368 } } ,
{ SPOOLSS_FORM_BUILTIN , " Letter Small " , { 0x34b5c , 0x44368 } , { 0x0 , 0x0 , 0x34b5c , 0x44368 } } ,
{ SPOOLSS_FORM_BUILTIN , " Tabloid " , { 0x44368 , 0x696b8 } , { 0x0 , 0x0 , 0x44368 , 0x696b8 } } ,
{ SPOOLSS_FORM_BUILTIN , " Ledger " , { 0x696b8 , 0x44368 } , { 0x0 , 0x0 , 0x696b8 , 0x44368 } } ,
{ SPOOLSS_FORM_BUILTIN , " Legal " , { 0x34b5c , 0x56d10 } , { 0x0 , 0x0 , 0x34b5c , 0x56d10 } } ,
{ SPOOLSS_FORM_BUILTIN , " Statement " , { 0x221b4 , 0x34b5c } , { 0x0 , 0x0 , 0x221b4 , 0x34b5c } } ,
{ SPOOLSS_FORM_BUILTIN , " Executive " , { 0x2cf56 , 0x411cc } , { 0x0 , 0x0 , 0x2cf56 , 0x411cc } } ,
{ SPOOLSS_FORM_BUILTIN , " A3 " , { 0x48828 , 0x668a0 } , { 0x0 , 0x0 , 0x48828 , 0x668a0 } } ,
{ SPOOLSS_FORM_BUILTIN , " A4 " , { 0x33450 , 0x48828 } , { 0x0 , 0x0 , 0x33450 , 0x48828 } } ,
{ SPOOLSS_FORM_BUILTIN , " A4 Small " , { 0x33450 , 0x48828 } , { 0x0 , 0x0 , 0x33450 , 0x48828 } } ,
{ SPOOLSS_FORM_BUILTIN , " A5 " , { 0x24220 , 0x33450 } , { 0x0 , 0x0 , 0x24220 , 0x33450 } } ,
{ SPOOLSS_FORM_BUILTIN , " B4 (JIS) " , { 0x3ebe8 , 0x58de0 } , { 0x0 , 0x0 , 0x3ebe8 , 0x58de0 } } ,
{ SPOOLSS_FORM_BUILTIN , " B5 (JIS) " , { 0x2c6f0 , 0x3ebe8 } , { 0x0 , 0x0 , 0x2c6f0 , 0x3ebe8 } } ,
{ SPOOLSS_FORM_BUILTIN , " Folio " , { 0x34b5c , 0x509d8 } , { 0x0 , 0x0 , 0x34b5c , 0x509d8 } } ,
{ SPOOLSS_FORM_BUILTIN , " Quarto " , { 0x347d8 , 0x43238 } , { 0x0 , 0x0 , 0x347d8 , 0x43238 } } ,
{ SPOOLSS_FORM_BUILTIN , " 10x14 " , { 0x3e030 , 0x56d10 } , { 0x0 , 0x0 , 0x3e030 , 0x56d10 } } ,
{ SPOOLSS_FORM_BUILTIN , " 11x17 " , { 0x44368 , 0x696b8 } , { 0x0 , 0x0 , 0x44368 , 0x696b8 } } ,
{ SPOOLSS_FORM_BUILTIN , " Note " , { 0x34b5c , 0x44368 } , { 0x0 , 0x0 , 0x34b5c , 0x44368 } } ,
{ SPOOLSS_FORM_BUILTIN , " Envelope #9 " , { 0x18079 , 0x37091 } , { 0x0 , 0x0 , 0x18079 , 0x37091 } } ,
{ SPOOLSS_FORM_BUILTIN , " Envelope #10 " , { 0x19947 , 0x3ae94 } , { 0x0 , 0x0 , 0x19947 , 0x3ae94 } } ,
{ SPOOLSS_FORM_BUILTIN , " Envelope #11 " , { 0x1be7c , 0x40565 } , { 0x0 , 0x0 , 0x1be7c , 0x40565 } } ,
{ SPOOLSS_FORM_BUILTIN , " Envelope #12 " , { 0x1d74a , 0x44368 } , { 0x0 , 0x0 , 0x1d74a , 0x44368 } } ,
{ SPOOLSS_FORM_BUILTIN , " Envelope #14 " , { 0x1f018 , 0x47504 } , { 0x0 , 0x0 , 0x1f018 , 0x47504 } } ,
{ SPOOLSS_FORM_BUILTIN , " C size sheet " , { 0x696b8 , 0x886d0 } , { 0x0 , 0x0 , 0x696b8 , 0x886d0 } } ,
{ SPOOLSS_FORM_BUILTIN , " D size sheet " , { 0x886d0 , 0xd2d70 } , { 0x0 , 0x0 , 0x886d0 , 0xd2d70 } } ,
{ SPOOLSS_FORM_BUILTIN , " E size sheet " , { 0xd2d70 , 0x110da0 } , { 0x0 , 0x0 , 0xd2d70 , 0x110da0 } } ,
{ SPOOLSS_FORM_BUILTIN , " Envelope DL " , { 0x1adb0 , 0x35b60 } , { 0x0 , 0x0 , 0x1adb0 , 0x35b60 } } ,
{ SPOOLSS_FORM_BUILTIN , " Envelope C5 " , { 0x278d0 , 0x37e88 } , { 0x0 , 0x0 , 0x278d0 , 0x37e88 } } ,
{ SPOOLSS_FORM_BUILTIN , " Envelope C3 " , { 0x4f1a0 , 0x6fd10 } , { 0x0 , 0x0 , 0x4f1a0 , 0x6fd10 } } ,
{ SPOOLSS_FORM_BUILTIN , " Envelope C4 " , { 0x37e88 , 0x4f1a0 } , { 0x0 , 0x0 , 0x37e88 , 0x4f1a0 } } ,
{ SPOOLSS_FORM_BUILTIN , " Envelope C6 " , { 0x1bd50 , 0x278d0 } , { 0x0 , 0x0 , 0x1bd50 , 0x278d0 } } ,
{ SPOOLSS_FORM_BUILTIN , " Envelope C65 " , { 0x1bd50 , 0x37e88 } , { 0x0 , 0x0 , 0x1bd50 , 0x37e88 } } ,
{ SPOOLSS_FORM_BUILTIN , " Envelope B4 " , { 0x3d090 , 0x562e8 } , { 0x0 , 0x0 , 0x3d090 , 0x562e8 } } ,
{ SPOOLSS_FORM_BUILTIN , " Envelope B5 " , { 0x2af80 , 0x3d090 } , { 0x0 , 0x0 , 0x2af80 , 0x3d090 } } ,
{ SPOOLSS_FORM_BUILTIN , " Envelope B6 " , { 0x2af80 , 0x1e848 } , { 0x0 , 0x0 , 0x2af80 , 0x1e848 } } ,
{ SPOOLSS_FORM_BUILTIN , " Envelope " , { 0x1adb0 , 0x38270 } , { 0x0 , 0x0 , 0x1adb0 , 0x38270 } } ,
{ SPOOLSS_FORM_BUILTIN , " Envelope Monarch " , { 0x18079 , 0x2e824 } , { 0x0 , 0x0 , 0x18079 , 0x2e824 } } ,
{ SPOOLSS_FORM_BUILTIN , " 6 3/4 Envelope " , { 0x167ab , 0x284ec } , { 0x0 , 0x0 , 0x167ab , 0x284ec } } ,
{ SPOOLSS_FORM_BUILTIN , " US Std Fanfold " , { 0x5c3e1 , 0x44368 } , { 0x0 , 0x0 , 0x5c3e1 , 0x44368 } } ,
{ SPOOLSS_FORM_BUILTIN , " German Std Fanfold " , { 0x34b5c , 0x4a6a0 } , { 0x0 , 0x0 , 0x34b5c , 0x4a6a0 } } ,
{ SPOOLSS_FORM_BUILTIN , " German Legal Fanfold " , { 0x34b5c , 0x509d8 } , { 0x0 , 0x0 , 0x34b5c , 0x509d8 } } ,
{ SPOOLSS_FORM_BUILTIN , " B4 (ISO) " , { 0x3d090 , 0x562e8 } , { 0x0 , 0x0 , 0x3d090 , 0x562e8 } } ,
{ SPOOLSS_FORM_BUILTIN , " Japanese Postcard " , { 0x186a0 , 0x24220 } , { 0x0 , 0x0 , 0x186a0 , 0x24220 } } ,
{ SPOOLSS_FORM_BUILTIN , " 9x11 " , { 0x37cf8 , 0x44368 } , { 0x0 , 0x0 , 0x37cf8 , 0x44368 } } ,
{ SPOOLSS_FORM_BUILTIN , " 10x11 " , { 0x3e030 , 0x44368 } , { 0x0 , 0x0 , 0x3e030 , 0x44368 } } ,
{ SPOOLSS_FORM_BUILTIN , " 15x11 " , { 0x5d048 , 0x44368 } , { 0x0 , 0x0 , 0x5d048 , 0x44368 } } ,
{ SPOOLSS_FORM_BUILTIN , " Envelope Invite " , { 0x35b60 , 0x35b60 } , { 0x0 , 0x0 , 0x35b60 , 0x35b60 } } ,
{ SPOOLSS_FORM_BUILTIN , " Reserved48 " , { 0x1 , 0x1 } , { 0x0 , 0x0 , 0x1 , 0x1 } } ,
{ SPOOLSS_FORM_BUILTIN , " Reserved49 " , { 0x1 , 0x1 } , { 0x0 , 0x0 , 0x1 , 0x1 } } ,
{ SPOOLSS_FORM_BUILTIN , " Letter Extra " , { 0x3ae94 , 0x4a6a0 } , { 0x0 , 0x0 , 0x3ae94 , 0x4a6a0 } } ,
{ SPOOLSS_FORM_BUILTIN , " Legal Extra " , { 0x3ae94 , 0x5d048 } , { 0x0 , 0x0 , 0x3ae94 , 0x5d048 } } ,
{ SPOOLSS_FORM_BUILTIN , " Tabloid Extra " , { 0x4a6a0 , 0x6f9f0 } , { 0x0 , 0x0 , 0x4a6a0 , 0x6f9f0 } } ,
{ SPOOLSS_FORM_BUILTIN , " A4 Extra " , { 0x397c2 , 0x4eb16 } , { 0x0 , 0x0 , 0x397c2 , 0x4eb16 } } ,
{ SPOOLSS_FORM_BUILTIN , " Letter Transverse " , { 0x34b5c , 0x44368 } , { 0x0 , 0x0 , 0x34b5c , 0x44368 } } ,
{ SPOOLSS_FORM_BUILTIN , " A4 Transverse " , { 0x33450 , 0x48828 } , { 0x0 , 0x0 , 0x33450 , 0x48828 } } ,
{ SPOOLSS_FORM_BUILTIN , " Letter Extra Transverse " , { 0x3ae94 , 0x4a6a0 } , { 0x0 , 0x0 , 0x3ae94 , 0x4a6a0 } } ,
{ SPOOLSS_FORM_BUILTIN , " Super A " , { 0x376b8 , 0x56ea0 } , { 0x0 , 0x0 , 0x376b8 , 0x56ea0 } } ,
{ SPOOLSS_FORM_BUILTIN , " Super B " , { 0x4a768 , 0x76e58 } , { 0x0 , 0x0 , 0x4a768 , 0x76e58 } } ,
{ SPOOLSS_FORM_BUILTIN , " Letter Plus " , { 0x34b5c , 0x4eb16 } , { 0x0 , 0x0 , 0x34b5c , 0x4eb16 } } ,
{ SPOOLSS_FORM_BUILTIN , " A4 Plus " , { 0x33450 , 0x50910 } , { 0x0 , 0x0 , 0x33450 , 0x50910 } } ,
{ SPOOLSS_FORM_BUILTIN , " A5 Transverse " , { 0x24220 , 0x33450 } , { 0x0 , 0x0 , 0x24220 , 0x33450 } } ,
{ SPOOLSS_FORM_BUILTIN , " B5 (JIS) Transverse " , { 0x2c6f0 , 0x3ebe8 } , { 0x0 , 0x0 , 0x2c6f0 , 0x3ebe8 } } ,
{ SPOOLSS_FORM_BUILTIN , " A3 Extra " , { 0x4e9d0 , 0x6ca48 } , { 0x0 , 0x0 , 0x4e9d0 , 0x6ca48 } } ,
{ SPOOLSS_FORM_BUILTIN , " A5 Extra " , { 0x2a7b0 , 0x395f8 } , { 0x0 , 0x0 , 0x2a7b0 , 0x395f8 } } ,
{ SPOOLSS_FORM_BUILTIN , " B5 (ISO) Extra " , { 0x31128 , 0x43620 } , { 0x0 , 0x0 , 0x31128 , 0x43620 } } ,
{ SPOOLSS_FORM_BUILTIN , " A2 " , { 0x668a0 , 0x91050 } , { 0x0 , 0x0 , 0x668a0 , 0x91050 } } ,
{ SPOOLSS_FORM_BUILTIN , " A3 Transverse " , { 0x48828 , 0x668a0 } , { 0x0 , 0x0 , 0x48828 , 0x668a0 } } ,
{ SPOOLSS_FORM_BUILTIN , " A3 Extra Transverse " , { 0x4e9d0 , 0x6ca48 } , { 0x0 , 0x0 , 0x4e9d0 , 0x6ca48 } } ,
{ SPOOLSS_FORM_BUILTIN , " Japanese Double Postcard " , { 0x30d40 , 0x24220 } , { 0x0 , 0x0 , 0x30d40 , 0x24220 } } ,
{ SPOOLSS_FORM_BUILTIN , " A6 " , { 0x19a28 , 0x24220 } , { 0x0 , 0x0 , 0x19a28 , 0x24220 } } ,
{ SPOOLSS_FORM_BUILTIN , " Japanese Envelope Kaku #2 " , { 0x3a980 , 0x510e0 } , { 0x0 , 0x0 , 0x3a980 , 0x510e0 } } ,
{ SPOOLSS_FORM_BUILTIN , " Japanese Envelope Kaku #3 " , { 0x34bc0 , 0x43a08 } , { 0x0 , 0x0 , 0x34bc0 , 0x43a08 } } ,
{ SPOOLSS_FORM_BUILTIN , " Japanese Envelope Chou #3 " , { 0x1d4c0 , 0x395f8 } , { 0x0 , 0x0 , 0x1d4c0 , 0x395f8 } } ,
{ SPOOLSS_FORM_BUILTIN , " Japanese Envelope Chou #4 " , { 0x15f90 , 0x320c8 } , { 0x0 , 0x0 , 0x15f90 , 0x320c8 } } ,
{ SPOOLSS_FORM_BUILTIN , " Letter Rotated " , { 0x44368 , 0x34b5c } , { 0x0 , 0x0 , 0x44368 , 0x34b5c } } ,
{ SPOOLSS_FORM_BUILTIN , " A3 Rotated " , { 0x668a0 , 0x48828 } , { 0x0 , 0x0 , 0x668a0 , 0x48828 } } ,
{ SPOOLSS_FORM_BUILTIN , " A4 Rotated " , { 0x48828 , 0x33450 } , { 0x0 , 0x0 , 0x48828 , 0x33450 } } ,
{ SPOOLSS_FORM_BUILTIN , " A5 Rotated " , { 0x33450 , 0x24220 } , { 0x0 , 0x0 , 0x33450 , 0x24220 } } ,
{ SPOOLSS_FORM_BUILTIN , " B4 (JIS) Rotated " , { 0x58de0 , 0x3ebe8 } , { 0x0 , 0x0 , 0x58de0 , 0x3ebe8 } } ,
{ SPOOLSS_FORM_BUILTIN , " B5 (JIS) Rotated " , { 0x3ebe8 , 0x2c6f0 } , { 0x0 , 0x0 , 0x3ebe8 , 0x2c6f0 } } ,
{ SPOOLSS_FORM_BUILTIN , " Japanese Postcard Rotated " , { 0x24220 , 0x186a0 } , { 0x0 , 0x0 , 0x24220 , 0x186a0 } } ,
{ SPOOLSS_FORM_BUILTIN , " Double Japan Postcard Rotated " , { 0x24220 , 0x30d40 } , { 0x0 , 0x0 , 0x24220 , 0x30d40 } } ,
{ SPOOLSS_FORM_BUILTIN , " A6 Rotated " , { 0x24220 , 0x19a28 } , { 0x0 , 0x0 , 0x24220 , 0x19a28 } } ,
{ SPOOLSS_FORM_BUILTIN , " Japan Envelope Kaku #2 Rotated " , { 0x510e0 , 0x3a980 } , { 0x0 , 0x0 , 0x510e0 , 0x3a980 } } ,
{ SPOOLSS_FORM_BUILTIN , " Japan Envelope Kaku #3 Rotated " , { 0x43a08 , 0x34bc0 } , { 0x0 , 0x0 , 0x43a08 , 0x34bc0 } } ,
{ SPOOLSS_FORM_BUILTIN , " Japan Envelope Chou #3 Rotated " , { 0x395f8 , 0x1d4c0 } , { 0x0 , 0x0 , 0x395f8 , 0x1d4c0 } } ,
{ SPOOLSS_FORM_BUILTIN , " Japan Envelope Chou #4 Rotated " , { 0x320c8 , 0x15f90 } , { 0x0 , 0x0 , 0x320c8 , 0x15f90 } } ,
{ SPOOLSS_FORM_BUILTIN , " B6 (JIS) " , { 0x1f400 , 0x2c6f0 } , { 0x0 , 0x0 , 0x1f400 , 0x2c6f0 } } ,
{ SPOOLSS_FORM_BUILTIN , " B6 (JIS) Rotated " , { 0x2c6f0 , 0x1f400 } , { 0x0 , 0x0 , 0x2c6f0 , 0x1f400 } } ,
{ SPOOLSS_FORM_BUILTIN , " 12x11 " , { 0x4a724 , 0x443e1 } , { 0x0 , 0x0 , 0x4a724 , 0x443e1 } } ,
{ SPOOLSS_FORM_BUILTIN , " Japan Envelope You #4 " , { 0x19a28 , 0x395f8 } , { 0x0 , 0x0 , 0x19a28 , 0x395f8 } } ,
{ SPOOLSS_FORM_BUILTIN , " Japan Envelope You #4 Rotated " , { 0x395f8 , 0x19a28 } , { 0x0 , 0x0 , 0x395f8 , 0x19a28 } } ,
{ SPOOLSS_FORM_BUILTIN , " PRC 16K " , { 0x2de60 , 0x3f7a0 } , { 0x0 , 0x0 , 0x2de60 , 0x3f7a0 } } ,
{ SPOOLSS_FORM_BUILTIN , " PRC 32K " , { 0x1fbd0 , 0x2cec0 } , { 0x0 , 0x0 , 0x1fbd0 , 0x2cec0 } } ,
{ SPOOLSS_FORM_BUILTIN , " PRC 32K(Big) " , { 0x222e0 , 0x318f8 } , { 0x0 , 0x0 , 0x222e0 , 0x318f8 } } ,
{ SPOOLSS_FORM_BUILTIN , " PRC Envelope #1 " , { 0x18e70 , 0x28488 } , { 0x0 , 0x0 , 0x18e70 , 0x28488 } } ,
{ SPOOLSS_FORM_BUILTIN , " PRC Envelope #2 " , { 0x18e70 , 0x2af80 } , { 0x0 , 0x0 , 0x18e70 , 0x2af80 } } ,
{ SPOOLSS_FORM_BUILTIN , " PRC Envelope #3 " , { 0x1e848 , 0x2af80 } , { 0x0 , 0x0 , 0x1e848 , 0x2af80 } } ,
{ SPOOLSS_FORM_BUILTIN , " PRC Envelope #4 " , { 0x1adb0 , 0x32c80 } , { 0x0 , 0x0 , 0x1adb0 , 0x32c80 } } ,
{ SPOOLSS_FORM_BUILTIN , " PRC Envelope #5 " , { 0x1adb0 , 0x35b60 } , { 0x0 , 0x0 , 0x1adb0 , 0x35b60 } } ,
{ SPOOLSS_FORM_BUILTIN , " PRC Envelope #6 " , { 0x1d4c0 , 0x38270 } , { 0x0 , 0x0 , 0x1d4c0 , 0x38270 } } ,
{ SPOOLSS_FORM_BUILTIN , " PRC Envelope #7 " , { 0x27100 , 0x38270 } , { 0x0 , 0x0 , 0x27100 , 0x38270 } } ,
{ SPOOLSS_FORM_BUILTIN , " PRC Envelope #8 " , { 0x1d4c0 , 0x4b708 } , { 0x0 , 0x0 , 0x1d4c0 , 0x4b708 } } ,
{ SPOOLSS_FORM_BUILTIN , " PRC Envelope #9 " , { 0x37e88 , 0x4f1a0 } , { 0x0 , 0x0 , 0x37e88 , 0x4f1a0 } } ,
{ SPOOLSS_FORM_BUILTIN , " PRC Envelope #10 " , { 0x4f1a0 , 0x6fd10 } , { 0x0 , 0x0 , 0x4f1a0 , 0x6fd10 } } ,
{ SPOOLSS_FORM_BUILTIN , " PRC 16K Rotated " , { 0x3f7a0 , 0x2de60 } , { 0x0 , 0x0 , 0x3f7a0 , 0x2de60 } } ,
{ SPOOLSS_FORM_BUILTIN , " PRC 32K Rotated " , { 0x2cec0 , 0x1fbd0 } , { 0x0 , 0x0 , 0x2cec0 , 0x1fbd0 } } ,
{ SPOOLSS_FORM_BUILTIN , " PRC 32K(Big) Rotated " , { 0x318f8 , 0x222e0 } , { 0x0 , 0x0 , 0x318f8 , 0x222e0 } } ,
{ SPOOLSS_FORM_BUILTIN , " PRC Envelope #1 Rotated " , { 0x28488 , 0x18e70 } , { 0x0 , 0x0 , 0x28488 , 0x18e70 } } ,
{ SPOOLSS_FORM_BUILTIN , " PRC Envelope #2 Rotated " , { 0x2af80 , 0x18e70 } , { 0x0 , 0x0 , 0x2af80 , 0x18e70 } } ,
{ SPOOLSS_FORM_BUILTIN , " PRC Envelope #3 Rotated " , { 0x2af80 , 0x1e848 } , { 0x0 , 0x0 , 0x2af80 , 0x1e848 } } ,
{ SPOOLSS_FORM_BUILTIN , " PRC Envelope #4 Rotated " , { 0x32c80 , 0x1adb0 } , { 0x0 , 0x0 , 0x32c80 , 0x1adb0 } } ,
{ SPOOLSS_FORM_BUILTIN , " PRC Envelope #5 Rotated " , { 0x35b60 , 0x1adb0 } , { 0x0 , 0x0 , 0x35b60 , 0x1adb0 } } ,
{ SPOOLSS_FORM_BUILTIN , " PRC Envelope #6 Rotated " , { 0x38270 , 0x1d4c0 } , { 0x0 , 0x0 , 0x38270 , 0x1d4c0 } } ,
{ SPOOLSS_FORM_BUILTIN , " PRC Envelope #7 Rotated " , { 0x38270 , 0x27100 } , { 0x0 , 0x0 , 0x38270 , 0x27100 } } ,
{ SPOOLSS_FORM_BUILTIN , " PRC Envelope #8 Rotated " , { 0x4b708 , 0x1d4c0 } , { 0x0 , 0x0 , 0x4b708 , 0x1d4c0 } } ,
{ SPOOLSS_FORM_BUILTIN , " PRC Envelope #9 Rotated " , { 0x4f1a0 , 0x37e88 } , { 0x0 , 0x0 , 0x4f1a0 , 0x37e88 } } ,
{ SPOOLSS_FORM_BUILTIN , " PRC Envelope #10 Rotated " , { 0x6fd10 , 0x4f1a0 } , { 0x0 , 0x0 , 0x6fd10 , 0x4f1a0 } }
} ;
2010-03-12 19:31:21 +03:00
/********************************************************************
static helper functions
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-04-15 17:18:26 +04:00
/****************************************************************************
Update the changeid time .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/**
* @ internal
*
* @ brief Update the ChangeID time of a printer .
*
* This is SO NASTY as some drivers need this to change , others need it
* static . This value will change every second , and I must hope that this
* is enough . . . . . DON ' T CHANGE THIS CODE WITHOUT A TEST MATRIX THE SIZE OF
* UTAH ! JRA .
*
* @ return The ChangeID .
*/
static uint32_t winreg_printer_rev_changeid ( void )
{
struct timeval tv ;
get_process_uptime ( & tv ) ;
# if 1 /* JERRY */
/* Return changeid as msec since spooler restart */
return tv . tv_sec * 1000 + tv . tv_usec / 1000 ;
# else
/*
* This setting seems to work well but is too untested
* to replace the above calculation . Left in for experiementation
* of the reader - - jerry ( Tue Mar 12 09 : 15 : 05 CST 2002 )
*/
return tv . tv_sec * 10 + tv . tv_usec / 100000 ;
# endif
}
2010-04-21 14:56:39 +04:00
static struct spoolss_security_descriptor * winreg_printer_create_default_secdesc ( TALLOC_CTX * ctx )
{
SEC_ACE ace [ 5 ] ; /* max number of ace entries */
int i = 0 ;
uint32_t sa ;
SEC_ACL * psa = NULL ;
SEC_DESC * psd = NULL ;
DOM_SID adm_sid ;
size_t sd_size ;
/* Create an ACE where Everyone is allowed to print */
sa = PRINTER_ACE_PRINT ;
init_sec_ace ( & ace [ i + + ] , & global_sid_World , SEC_ACE_TYPE_ACCESS_ALLOWED ,
sa , SEC_ACE_FLAG_CONTAINER_INHERIT ) ;
/* Add the domain admins group if we are a DC */
if ( IS_DC ) {
DOM_SID domadmins_sid ;
sid_compose ( & domadmins_sid , get_global_sam_sid ( ) ,
DOMAIN_GROUP_RID_ADMINS ) ;
sa = PRINTER_ACE_FULL_CONTROL ;
init_sec_ace ( & ace [ i + + ] , & domadmins_sid ,
SEC_ACE_TYPE_ACCESS_ALLOWED , sa ,
SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY ) ;
init_sec_ace ( & ace [ i + + ] , & domadmins_sid , SEC_ACE_TYPE_ACCESS_ALLOWED ,
sa , SEC_ACE_FLAG_CONTAINER_INHERIT ) ;
}
else if ( secrets_fetch_domain_sid ( lp_workgroup ( ) , & adm_sid ) ) {
sid_append_rid ( & adm_sid , DOMAIN_USER_RID_ADMIN ) ;
sa = PRINTER_ACE_FULL_CONTROL ;
init_sec_ace ( & ace [ i + + ] , & adm_sid ,
SEC_ACE_TYPE_ACCESS_ALLOWED , sa ,
SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY ) ;
init_sec_ace ( & ace [ i + + ] , & adm_sid , SEC_ACE_TYPE_ACCESS_ALLOWED ,
sa , SEC_ACE_FLAG_CONTAINER_INHERIT ) ;
}
/* add BUILTIN\Administrators as FULL CONTROL */
sa = PRINTER_ACE_FULL_CONTROL ;
init_sec_ace ( & ace [ i + + ] , & global_sid_Builtin_Administrators ,
SEC_ACE_TYPE_ACCESS_ALLOWED , sa ,
SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY ) ;
init_sec_ace ( & ace [ i + + ] , & global_sid_Builtin_Administrators ,
SEC_ACE_TYPE_ACCESS_ALLOWED ,
sa , SEC_ACE_FLAG_CONTAINER_INHERIT ) ;
/* Make the security descriptor owned by the BUILTIN\Administrators */
/* The ACL revision number in rpc_secdesc.h differs from the one
created by NT when setting ACE entries in printer
descriptors . NT4 complains about the property being edited by a
NT5 machine . */
if ( ( psa = make_sec_acl ( ctx , NT4_ACL_REVISION , i , ace ) ) ! = NULL ) {
psd = make_sec_desc ( ctx , SEC_DESC_REVISION , SEC_DESC_SELF_RELATIVE ,
& global_sid_Builtin_Administrators ,
& global_sid_Builtin_Administrators ,
NULL , psa , & sd_size ) ;
}
if ( ! psd ) {
DEBUG ( 0 , ( " construct_default_printer_sd: Failed to make SEC_DESC. \n " ) ) ;
return NULL ;
}
DEBUG ( 4 , ( " construct_default_printer_sdb: size = %u. \n " ,
( unsigned int ) sd_size ) ) ;
return psd ;
}
static struct spoolss_DeviceMode * winreg_printer_create_default_devmode ( TALLOC_CTX * mem_ctx ,
const char * default_devicename )
{
char adevice [ MAXDEVICENAME ] ;
struct spoolss_DeviceMode * devmode ;
devmode = talloc_zero ( mem_ctx , struct spoolss_DeviceMode ) ;
if ( devmode = = NULL ) {
return NULL ;
}
slprintf ( adevice , sizeof ( adevice ) , " %s " , default_devicename ) ;
devmode - > devicename = talloc_strdup ( mem_ctx , adevice ) ;
if ( devmode - > devicename = = NULL ) {
return NULL ;
}
devmode - > formname = " Letter " ;
devmode - > specversion = DMSPEC_NT4_AND_ABOVE ;
devmode - > driverversion = 0x0400 ;
devmode - > size = 0x00DC ;
devmode - > __driverextra_length = 0 ;
devmode - > fields = DEVMODE_FORMNAME |
DEVMODE_TTOPTION |
DEVMODE_PRINTQUALITY |
DEVMODE_DEFAULTSOURCE |
DEVMODE_COPIES |
DEVMODE_SCALE |
DEVMODE_PAPERSIZE |
DEVMODE_ORIENTATION ;
devmode - > orientation = DMORIENT_PORTRAIT ;
devmode - > papersize = DMPAPER_LETTER ;
devmode - > paperlength = 0 ;
devmode - > paperwidth = 0 ;
devmode - > scale = 0x64 ;
devmode - > copies = 1 ;
devmode - > defaultsource = DMBIN_FORMSOURCE ;
devmode - > printquality = DMRES_HIGH ; /* 0x0258 */
devmode - > color = DMRES_MONOCHROME ;
devmode - > duplex = DMDUP_SIMPLEX ;
devmode - > yresolution = 0 ;
devmode - > ttoption = DMTT_SUBDEV ;
devmode - > collate = DMCOLLATE_FALSE ;
devmode - > icmmethod = 0 ;
devmode - > icmintent = 0 ;
devmode - > mediatype = 0 ;
devmode - > dithertype = 0 ;
devmode - > logpixels = 0 ;
devmode - > bitsperpel = 0 ;
devmode - > pelswidth = 0 ;
devmode - > pelsheight = 0 ;
devmode - > displayflags = 0 ;
devmode - > displayfrequency = 0 ;
devmode - > reserved1 = 0 ;
devmode - > reserved2 = 0 ;
devmode - > panningwidth = 0 ;
devmode - > panningheight = 0 ;
devmode - > driverextra_data . data = NULL ;
devmode - > driverextra_data . length = 0 ;
return devmode ;
}
2010-03-15 14:24:40 +03:00
/**
* @ internal
*
* @ brief Connect to the interal winreg server and open the given printer key .
*
* The function will create the needed subkeys if they don ' t exist .
*
* @ param [ in ] mem_ctx The memory context to use .
*
* @ param [ in ] server_info The supplied server info .
*
* @ param [ out ] winreg_pipe A pointer for the winreg rpc client pipe .
*
2010-03-30 16:46:32 +04:00
* @ param [ in ] path The path to the key to open .
2010-03-15 14:24:40 +03:00
*
* @ param [ in ] key The key to open .
*
* @ param [ in ] create_key Set to true if the key should be created if it
* doesn ' t exist .
*
* @ param [ in ] access_mask The access mask to open the key .
*
* @ param [ out ] hive_handle A policy handle for the opened hive .
*
* @ param [ out ] key_handle A policy handle for the opened key .
*
* @ return WERR_OK on success , the corresponding DOS error
* code if something gone wrong .
*/
static WERROR winreg_printer_openkey ( TALLOC_CTX * mem_ctx ,
struct auth_serversupplied_info * server_info ,
struct rpc_pipe_client * * winreg_pipe ,
2010-03-30 16:46:32 +04:00
const char * path ,
2010-03-15 14:24:40 +03:00
const char * key ,
bool create_key ,
uint32_t access_mask ,
struct policy_handle * hive_handle ,
struct policy_handle * key_handle )
{
struct rpc_pipe_client * pipe_handle ;
struct winreg_String wkey , wkeyclass ;
char * keyname ;
NTSTATUS status ;
WERROR result = WERR_OK ;
/* create winreg connection */
status = rpc_pipe_open_internal ( mem_ctx ,
& ndr_table_winreg . syntax_id ,
rpc_winreg_dispatch ,
server_info ,
& pipe_handle ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 0 , ( " winreg_printer_openkey: Could not connect to winreg_pipe: %s \n " ,
nt_errstr ( status ) ) ) ;
return ntstatus_to_werror ( status ) ;
}
status = rpccli_winreg_OpenHKLM ( pipe_handle ,
mem_ctx ,
NULL ,
access_mask ,
hive_handle ,
& result ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 0 , ( " winreg_printer_openkey: Could not open HKLM hive: %s \n " ,
nt_errstr ( status ) ) ) ;
talloc_free ( pipe_handle ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
return result ;
}
return ntstatus_to_werror ( status ) ;
}
if ( key & & * key ) {
2010-03-30 16:46:32 +04:00
keyname = talloc_asprintf ( mem_ctx , " %s \\ %s " , path , key ) ;
2010-03-15 14:24:40 +03:00
} else {
2010-03-30 16:46:32 +04:00
keyname = talloc_strdup ( mem_ctx , path ) ;
2010-03-15 14:24:40 +03:00
}
if ( keyname = = NULL ) {
talloc_free ( pipe_handle ) ;
return WERR_NOMEM ;
}
ZERO_STRUCT ( wkey ) ;
wkey . name = keyname ;
if ( create_key ) {
enum winreg_CreateAction action = REG_ACTION_NONE ;
ZERO_STRUCT ( wkeyclass ) ;
wkeyclass . name = " " ;
status = rpccli_winreg_CreateKey ( pipe_handle ,
mem_ctx ,
hive_handle ,
wkey ,
wkeyclass ,
0 ,
access_mask ,
NULL ,
key_handle ,
& action ,
& result ) ;
switch ( action ) {
case REG_ACTION_NONE :
DEBUG ( 8 , ( " winreg_printer_openkey:createkey did nothing -- huh? \n " ) ) ;
break ;
case REG_CREATED_NEW_KEY :
DEBUG ( 8 , ( " winreg_printer_openkey: createkey created %s \n " , keyname ) ) ;
break ;
case REG_OPENED_EXISTING_KEY :
DEBUG ( 8 , ( " winreg_printer_openkey: createkey opened existing %s \n " , keyname ) ) ;
break ;
}
} else {
status = rpccli_winreg_OpenKey ( pipe_handle ,
mem_ctx ,
hive_handle ,
wkey ,
0 ,
access_mask ,
key_handle ,
& result ) ;
}
if ( ! NT_STATUS_IS_OK ( status ) ) {
talloc_free ( pipe_handle ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
return result ;
}
return ntstatus_to_werror ( status ) ;
}
* winreg_pipe = pipe_handle ;
return WERR_OK ;
}
2010-03-15 14:24:59 +03:00
2010-03-30 16:46:32 +04:00
/**
* @ brief Create the registry keyname for the given printer .
*
* @ param [ in ] mem_ctx The memory context to use .
*
* @ param [ in ] printer The name of the printer to get the registry key .
*
* @ return The registry key or NULL on error .
*/
static char * winreg_printer_data_keyname ( TALLOC_CTX * mem_ctx , const char * printer ) {
return talloc_asprintf ( mem_ctx , " %s \\ %s " , TOP_LEVEL_PRINT_PRINTERS_KEY , printer ) ;
}
2010-03-12 19:31:21 +03:00
/**
* @ internal
*
* @ brief Enumerate values of an opened key handle and retrieve the data .
*
* @ param [ in ] mem_ctx The memory context to use .
*
* @ param [ in ] pipe_handle The pipe handle for the rpc connection .
*
* @ param [ in ] key_hnd The opened key handle .
*
* @ param [ out ] pnum_values A pointer to store he number of values found .
*
* @ param [ out ] pnum_values A pointer to store the number of values we found .
*
* @ return WERR_OK on success , the corresponding DOS error
* code if something gone wrong .
*/
static WERROR winreg_printer_enumvalues ( TALLOC_CTX * mem_ctx ,
struct rpc_pipe_client * pipe_handle ,
struct policy_handle * key_hnd ,
uint32_t * pnum_values ,
struct spoolss_PrinterEnumValues * * penum_values )
{
TALLOC_CTX * tmp_ctx ;
uint32_t num_subkeys , max_subkeylen , max_classlen ;
uint32_t num_values , max_valnamelen , max_valbufsize ;
uint32_t secdescsize ;
uint32_t i ;
NTTIME last_changed_time ;
struct winreg_String classname ;
struct spoolss_PrinterEnumValues * enum_values ;
WERROR result = WERR_OK ;
NTSTATUS status ;
tmp_ctx = talloc_new ( mem_ctx ) ;
if ( tmp_ctx = = NULL ) {
return WERR_NOMEM ;
}
ZERO_STRUCT ( classname ) ;
status = rpccli_winreg_QueryInfoKey ( pipe_handle ,
tmp_ctx ,
key_hnd ,
& classname ,
& num_subkeys ,
& max_subkeylen ,
& max_classlen ,
& num_values ,
& max_valnamelen ,
& max_valbufsize ,
& secdescsize ,
& last_changed_time ,
& result ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 0 , ( " winreg_printer_enumvalues: Could not query info: %s \n " ,
nt_errstr ( status ) ) ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
goto error ;
}
result = ntstatus_to_werror ( status ) ;
goto error ;
}
if ( num_values = = 0 ) {
* pnum_values = 0 ;
TALLOC_FREE ( tmp_ctx ) ;
return WERR_OK ;
}
enum_values = TALLOC_ARRAY ( tmp_ctx , struct spoolss_PrinterEnumValues , num_values ) ;
if ( enum_values = = NULL ) {
result = WERR_NOMEM ;
goto error ;
}
for ( i = 0 ; i < num_values ; i + + ) {
struct spoolss_PrinterEnumValues val ;
struct winreg_ValNameBuf name_buf ;
enum winreg_Type type = REG_NONE ;
uint8_t * data = NULL ;
uint32_t data_size ;
uint32_t length ;
char n = ' \0 ' ; ;
name_buf . name = & n ;
name_buf . size = max_valnamelen + 2 ;
name_buf . length = 0 ;
data_size = max_valbufsize ;
data = ( uint8_t * ) TALLOC ( tmp_ctx , data_size ) ;
length = 0 ;
status = rpccli_winreg_EnumValue ( pipe_handle ,
tmp_ctx ,
key_hnd ,
i ,
& name_buf ,
& type ,
data ,
& data_size ,
& length ,
& result ) ;
if ( W_ERROR_EQUAL ( result , WERR_NO_MORE_ITEMS ) ) {
result = WERR_OK ;
status = NT_STATUS_OK ;
break ;
}
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 0 , ( " winreg_printer_enumvalues: Could not enumerate values: %s \n " ,
nt_errstr ( status ) ) ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
goto error ;
}
result = ntstatus_to_werror ( status ) ;
goto error ;
}
if ( name_buf . name = = NULL ) {
result = WERR_INVALID_PARAMETER ;
goto error ;
}
val . value_name = talloc_strdup ( enum_values , name_buf . name ) ;
if ( val . value_name = = NULL ) {
result = WERR_NOMEM ;
goto error ;
}
val . value_name_len = strlen_m_term ( val . value_name ) * 2 ;
val . type = type ;
val . data_length = data_size ;
2010-04-09 20:44:19 +04:00
val . data = NULL ;
2010-03-12 19:31:21 +03:00
if ( val . data_length ) {
val . data = talloc ( enum_values , DATA_BLOB ) ;
if ( val . data = = NULL ) {
result = WERR_NOMEM ;
goto error ;
}
* val . data = data_blob_talloc ( enum_values , data , data_size ) ;
}
enum_values [ i ] = val ;
}
* pnum_values = num_values ;
if ( penum_values ) {
* penum_values = talloc_move ( mem_ctx , & enum_values ) ;
}
result = WERR_OK ;
error :
TALLOC_FREE ( tmp_ctx ) ;
return result ;
}
2010-03-17 17:59:10 +03:00
/**
* @ internal
*
* @ brief Enumerate subkeys of an opened key handle and get the names .
*
* @ param [ in ] mem_ctx The memory context to use .
*
* @ param [ in ] pipe_handle The pipe handle for the rpc connection .
*
* @ param [ in ] key_hnd The opened key handle .
*
* @ param [ in ] pnum_subkeys A pointer to store the number of found subkeys .
*
* @ param [ in ] psubkeys A pointer to an array to store the found names of
* subkeys .
*
* @ return WERR_OK on success , the corresponding DOS error
* code if something gone wrong .
*/
static WERROR winreg_printer_enumkeys ( TALLOC_CTX * mem_ctx ,
struct rpc_pipe_client * pipe_handle ,
struct policy_handle * key_hnd ,
uint32_t * pnum_subkeys ,
const char * * * psubkeys )
{
TALLOC_CTX * tmp_ctx ;
const char * * subkeys ;
uint32_t num_subkeys , max_subkeylen , max_classlen ;
uint32_t num_values , max_valnamelen , max_valbufsize ;
uint32_t i ;
NTTIME last_changed_time ;
uint32_t secdescsize ;
struct winreg_String classname ;
WERROR result = WERR_OK ;
NTSTATUS status ;
tmp_ctx = talloc_new ( mem_ctx ) ;
if ( tmp_ctx = = NULL ) {
return WERR_NOMEM ;
}
ZERO_STRUCT ( classname ) ;
status = rpccli_winreg_QueryInfoKey ( pipe_handle ,
tmp_ctx ,
key_hnd ,
& classname ,
& num_subkeys ,
& max_subkeylen ,
& max_classlen ,
& num_values ,
& max_valnamelen ,
& max_valbufsize ,
& secdescsize ,
& last_changed_time ,
& result ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 0 , ( " winreg_printer_enumkeys: Could not query info: %s \n " ,
nt_errstr ( status ) ) ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
goto error ;
}
result = ntstatus_to_werror ( status ) ;
goto error ;
}
subkeys = talloc_zero_array ( tmp_ctx , const char * , num_subkeys + 2 ) ;
if ( subkeys = = NULL ) {
result = WERR_NOMEM ;
goto error ;
}
if ( num_subkeys = = 0 ) {
subkeys [ 0 ] = talloc_strdup ( subkeys , " " ) ;
if ( subkeys [ 0 ] = = NULL ) {
result = WERR_NOMEM ;
goto error ;
}
* pnum_subkeys = 0 ;
if ( psubkeys ) {
* psubkeys = talloc_move ( mem_ctx , & subkeys ) ;
}
TALLOC_FREE ( tmp_ctx ) ;
return WERR_OK ;
}
for ( i = 0 ; i < num_subkeys ; i + + ) {
char c = ' \0 ' ;
char n = ' \0 ' ;
char * name = NULL ;
struct winreg_StringBuf class_buf ;
struct winreg_StringBuf name_buf ;
NTTIME modtime ;
class_buf . name = & c ;
class_buf . size = max_classlen + 2 ;
class_buf . length = 0 ;
name_buf . name = & n ;
name_buf . size = max_subkeylen + 2 ;
name_buf . length = 0 ;
ZERO_STRUCT ( modtime ) ;
status = rpccli_winreg_EnumKey ( pipe_handle ,
tmp_ctx ,
key_hnd ,
i ,
& name_buf ,
& class_buf ,
& modtime ,
& result ) ;
if ( W_ERROR_EQUAL ( result , WERR_NO_MORE_ITEMS ) ) {
result = WERR_OK ;
status = NT_STATUS_OK ;
break ;
}
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 0 , ( " winreg_printer_enumkeys: Could not enumerate keys: %s \n " ,
nt_errstr ( status ) ) ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
goto error ;
}
result = ntstatus_to_werror ( status ) ;
goto error ;
}
if ( name_buf . name = = NULL ) {
result = WERR_INVALID_PARAMETER ;
goto error ;
}
name = talloc_strdup ( subkeys , name_buf . name ) ;
if ( name = = NULL ) {
result = WERR_NOMEM ;
goto error ;
}
subkeys [ i ] = name ;
}
* pnum_subkeys = num_subkeys ;
if ( psubkeys ) {
* psubkeys = talloc_move ( mem_ctx , & subkeys ) ;
}
error :
TALLOC_FREE ( tmp_ctx ) ;
return result ;
}
2010-04-06 19:01:15 +04:00
/**
* @ internal
*
* @ brief A function to delete a key and its subkeys recurively .
*
* @ param [ in ] mem_ctx The memory context to use .
*
* @ param [ in ] pipe_handle The pipe handle for the rpc connection .
*
* @ param [ in ] hive_handle A opened hive handle to the key .
*
* @ param [ in ] access_mask The access mask to access the key .
*
* @ param [ in ] key The key to delete
*
* @ return WERR_OK on success , the corresponding DOS error
* code if something gone wrong .
*/
static WERROR winreg_printer_delete_subkeys ( TALLOC_CTX * mem_ctx ,
struct rpc_pipe_client * pipe_handle ,
struct policy_handle * hive_handle ,
uint32_t access_mask ,
const char * key )
{
const char * * subkeys = NULL ;
uint32_t num_subkeys = 0 ;
struct policy_handle key_hnd ;
struct winreg_String wkey ;
WERROR result = WERR_OK ;
NTSTATUS status ;
uint32_t i ;
ZERO_STRUCT ( key_hnd ) ;
wkey . name = key ;
DEBUG ( 2 , ( " winreg_printer_delete_subkeys: delete key %s \n " , key ) ) ;
/* open the key */
status = rpccli_winreg_OpenKey ( pipe_handle ,
mem_ctx ,
hive_handle ,
wkey ,
0 ,
access_mask ,
& key_hnd ,
& result ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 0 , ( " winreg_printer_delete_subkeys: Could not open key %s: %s \n " ,
wkey . name , nt_errstr ( status ) ) ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
return result ;
}
return ntstatus_to_werror ( status ) ;
}
result = winreg_printer_enumkeys ( mem_ctx ,
pipe_handle ,
& key_hnd ,
& num_subkeys ,
& subkeys ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
goto done ;
}
for ( i = 0 ; i < num_subkeys ; i + + ) {
/* create key + subkey */
char * subkey = talloc_asprintf ( mem_ctx , " %s \\ %s " , key , subkeys [ i ] ) ;
if ( subkey = = NULL ) {
goto done ;
}
DEBUG ( 2 , ( " winreg_printer_delete_subkeys: delete subkey %s \n " , subkey ) ) ;
result = winreg_printer_delete_subkeys ( mem_ctx ,
pipe_handle ,
hive_handle ,
access_mask ,
subkey ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
goto done ;
}
}
if ( is_valid_policy_hnd ( & key_hnd ) ) {
rpccli_winreg_CloseKey ( pipe_handle , mem_ctx , & key_hnd , NULL ) ;
}
wkey . name = key ;
status = rpccli_winreg_DeleteKey ( pipe_handle ,
mem_ctx ,
hive_handle ,
wkey ,
& result ) ;
done :
if ( is_valid_policy_hnd ( & key_hnd ) ) {
rpccli_winreg_CloseKey ( pipe_handle , mem_ctx , & key_hnd , NULL ) ;
}
return result ;
}
2010-04-09 14:36:37 +04:00
static WERROR winreg_printer_write_sz ( TALLOC_CTX * mem_ctx ,
struct rpc_pipe_client * pipe_handle ,
struct policy_handle * key_handle ,
const char * value ,
const char * data )
{
struct winreg_String wvalue ;
DATA_BLOB blob ;
WERROR result = WERR_OK ;
NTSTATUS status ;
wvalue . name = value ;
if ( data = = NULL ) {
blob = data_blob_string_const ( " " ) ;
} else {
if ( ! push_reg_sz ( mem_ctx , NULL , & blob , data ) ) {
DEBUG ( 0 , ( " winreg_printer_write_sz: Could not marshall string %s for %s \n " ,
data , wvalue . name ) ) ;
return WERR_NOMEM ;
}
}
status = rpccli_winreg_SetValue ( pipe_handle ,
mem_ctx ,
key_handle ,
wvalue ,
REG_SZ ,
blob . data ,
blob . length ,
& result ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 0 , ( " winreg_printer_write_sz: Could not set value %s: %s \n " ,
wvalue . name , win_errstr ( result ) ) ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
result = ntstatus_to_werror ( status ) ;
}
}
return result ;
}
static WERROR winreg_printer_write_dword ( TALLOC_CTX * mem_ctx ,
struct rpc_pipe_client * pipe_handle ,
struct policy_handle * key_handle ,
const char * value ,
uint32_t data )
{
struct winreg_String wvalue ;
DATA_BLOB blob ;
WERROR result = WERR_OK ;
NTSTATUS status ;
wvalue . name = value ;
blob = data_blob_talloc ( mem_ctx , NULL , 4 ) ;
SIVAL ( blob . data , 0 , data ) ;
status = rpccli_winreg_SetValue ( pipe_handle ,
mem_ctx ,
key_handle ,
wvalue ,
REG_DWORD ,
blob . data ,
blob . length ,
& result ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 0 , ( " winreg_printer_write_dword: Could not set value %s: %s \n " ,
wvalue . name , win_errstr ( result ) ) ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
result = ntstatus_to_werror ( status ) ;
}
}
return result ;
}
static WERROR winreg_printer_write_binary ( TALLOC_CTX * mem_ctx ,
struct rpc_pipe_client * pipe_handle ,
struct policy_handle * key_handle ,
const char * value ,
DATA_BLOB blob )
{
struct winreg_String wvalue ;
WERROR result = WERR_OK ;
NTSTATUS status ;
wvalue . name = value ;
status = rpccli_winreg_SetValue ( pipe_handle ,
mem_ctx ,
key_handle ,
wvalue ,
REG_BINARY ,
blob . data ,
blob . length ,
& result ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 0 , ( " winreg_printer_write_binary: Could not set value %s: %s \n " ,
wvalue . name , win_errstr ( result ) ) ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
result = ntstatus_to_werror ( status ) ;
}
}
return result ;
}
2010-04-12 17:54:01 +04:00
static WERROR winreg_printer_query_dword ( TALLOC_CTX * mem_ctx ,
struct rpc_pipe_client * pipe_handle ,
struct policy_handle * key_handle ,
const char * value ,
uint32_t * data )
{
struct winreg_String wvalue ;
enum winreg_Type type ;
WERROR result = WERR_OK ;
uint32_t value_len = 0 ;
NTSTATUS status ;
DATA_BLOB blob ;
wvalue . name = value ;
status = rpccli_winreg_QueryValue ( pipe_handle ,
mem_ctx ,
key_handle ,
& wvalue ,
& type ,
NULL ,
( uint32_t * ) & blob . length ,
& value_len ,
& result ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 0 , ( " winreg_printer_query_dword: Could not query value %s: %s \n " ,
wvalue . name , nt_errstr ( status ) ) ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
goto done ;
}
result = ntstatus_to_werror ( status ) ;
goto done ;
}
if ( type ! = REG_DWORD ) {
result = WERR_INVALID_DATATYPE ;
goto done ;
}
if ( blob . length ! = 4 ) {
result = WERR_INVALID_DATA ;
goto done ;
}
blob . data = ( uint8_t * ) TALLOC ( mem_ctx , blob . length ) ;
if ( blob . data = = NULL ) {
result = WERR_NOMEM ;
goto done ;
}
value_len = 0 ;
status = rpccli_winreg_QueryValue ( pipe_handle ,
mem_ctx ,
key_handle ,
& wvalue ,
& type ,
blob . data ,
( uint32_t * ) & blob . length ,
& value_len ,
& result ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 0 , ( " winreg_printer_query_dword: Could not query value %s: %s \n " ,
wvalue . name , nt_errstr ( status ) ) ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
result = ntstatus_to_werror ( status ) ;
}
goto done ;
}
if ( data ) {
* data = IVAL ( blob . data , 0 ) ;
}
done :
return result ;
}
2010-04-21 17:51:37 +04:00
static WERROR winreg_printer_write_multi_sz ( TALLOC_CTX * mem_ctx ,
struct rpc_pipe_client * pipe_handle ,
struct policy_handle * key_handle ,
const char * value ,
const char * * data )
{
struct winreg_String wvalue ;
DATA_BLOB blob ;
WERROR result = WERR_OK ;
NTSTATUS status ;
wvalue . name = value ;
if ( ! push_reg_multi_sz ( mem_ctx , NULL , & blob , data ) ) {
return WERR_NOMEM ;
}
status = rpccli_winreg_SetValue ( pipe_handle ,
mem_ctx ,
key_handle ,
wvalue ,
REG_MULTI_SZ ,
blob . data ,
blob . length ,
& result ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 0 , ( " winreg_printer_write_multi_sz: Could not set value %s: %s \n " ,
wvalue . name , win_errstr ( result ) ) ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
result = ntstatus_to_werror ( status ) ;
}
}
return result ;
}
static WERROR winreg_printer_opendriver ( TALLOC_CTX * mem_ctx ,
struct auth_serversupplied_info * server_info ,
const char * drivername ,
const char * architecture ,
uint32_t version ,
uint32_t access_mask ,
bool create ,
struct rpc_pipe_client * * winreg_pipe ,
struct policy_handle * hive_hnd ,
struct policy_handle * key_hnd )
{
WERROR result ;
char * key_name ;
key_name = talloc_asprintf ( mem_ctx , " %s \\ Environments \\ %s \\ Drivers \\ Version-%u " ,
TOP_LEVEL_CONTROL_KEY ,
architecture , version ) ;
if ( ! key_name ) {
return WERR_NOMEM ;
}
result = winreg_printer_openkey ( mem_ctx ,
server_info ,
winreg_pipe ,
key_name ,
drivername ,
create ,
access_mask ,
hive_hnd ,
key_hnd ) ;
return result ;
}
static WERROR winreg_enumval_to_dword ( TALLOC_CTX * mem_ctx ,
struct spoolss_PrinterEnumValues * v ,
const char * valuename , uint32_t * dw )
{
/* just return if it is not the one we are looking for */
if ( strcmp ( valuename , v - > value_name ) ! = 0 ) {
return WERR_NOT_FOUND ;
}
if ( v - > type ! = REG_DWORD ) {
return WERR_INVALID_DATATYPE ;
}
* dw = IVAL ( v - > data - > data , 0 ) ;
return WERR_OK ;
}
static WERROR winreg_enumval_to_sz ( TALLOC_CTX * mem_ctx ,
struct spoolss_PrinterEnumValues * v ,
const char * valuename , const char * * _str )
{
/* just return if it is not the one we are looking for */
if ( strcmp ( valuename , v - > value_name ) ! = 0 ) {
return WERR_NOT_FOUND ;
}
if ( v - > type ! = REG_SZ ) {
return WERR_INVALID_DATATYPE ;
}
if ( ! pull_reg_sz ( mem_ctx , NULL , v - > data , _str ) ) {
return WERR_NOMEM ;
}
return WERR_OK ;
}
static WERROR winreg_enumval_to_multi_sz ( TALLOC_CTX * mem_ctx ,
struct spoolss_PrinterEnumValues * v ,
const char * valuename ,
const char * * * array )
{
/* just return if it is not the one we are looking for */
if ( strcmp ( valuename , v - > value_name ) ! = 0 ) {
return WERR_NOT_FOUND ;
}
if ( v - > type ! = REG_MULTI_SZ ) {
return WERR_INVALID_DATATYPE ;
}
if ( ! pull_reg_multi_sz ( mem_ctx , NULL , v - > data , array ) ) {
return WERR_NOMEM ;
}
return WERR_OK ;
}
2010-04-21 20:12:50 +04:00
static WERROR winreg_enumval_to_blob ( TALLOC_CTX * mem_ctx ,
struct spoolss_PrinterEnumValues * v ,
const char * valuename ,
DATA_BLOB * blob )
{
/* just return if it is not the one we are looking for */
if ( strcmp ( valuename , v - > value_name ) ! = 0 ) {
return WERR_NOT_FOUND ;
}
if ( v - > type ! = REG_BINARY ) {
return WERR_INVALID_DATATYPE ;
}
blob - > data = v - > data - > data ;
blob - > length = v - > data_length ;
return WERR_OK ;
}
2010-04-21 17:58:51 +04:00
static WERROR winreg_printer_write_date ( TALLOC_CTX * mem_ctx ,
struct rpc_pipe_client * pipe_handle ,
struct policy_handle * key_handle ,
const char * value ,
NTTIME data )
{
struct winreg_String wvalue ;
DATA_BLOB blob ;
WERROR result = WERR_OK ;
NTSTATUS status ;
const char * str ;
struct tm * tm ;
time_t t ;
t = nt_time_to_unix ( data ) ;
tm = localtime ( & t ) ;
str = talloc_asprintf ( mem_ctx , " %02d/%02d/%04d " ,
tm - > tm_mon + 1 , tm - > tm_mday , tm - > tm_year + 1900 ) ;
if ( ! str ) {
return WERR_NOMEM ;
}
wvalue . name = value ;
if ( ! push_reg_sz ( mem_ctx , NULL , & blob , str ) ) {
return WERR_NOMEM ;
}
status = rpccli_winreg_SetValue ( pipe_handle ,
mem_ctx ,
key_handle ,
wvalue ,
REG_SZ ,
blob . data ,
blob . length ,
& result ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 0 , ( " winreg_printer_write_date: Could not set value %s: %s \n " ,
wvalue . name , win_errstr ( result ) ) ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
result = ntstatus_to_werror ( status ) ;
}
}
return result ;
}
static WERROR winreg_printer_date_to_NTTIME ( const char * str , NTTIME * data )
{
struct tm tm ;
time_t t ;
ZERO_STRUCT ( tm ) ;
if ( sscanf ( str , " %d/%d/%d " ,
& tm . tm_mon , & tm . tm_mday , & tm . tm_year ) ! = 3 ) {
return WERR_INVALID_PARAMETER ;
}
tm . tm_mon - = 1 ;
tm . tm_year - = 1900 ;
tm . tm_isdst = - 1 ;
t = mktime ( & tm ) ;
unix_to_nt_time ( data , t ) ;
return WERR_OK ;
}
static WERROR winreg_printer_write_ver ( TALLOC_CTX * mem_ctx ,
struct rpc_pipe_client * pipe_handle ,
struct policy_handle * key_handle ,
const char * value ,
uint64_t data )
{
struct winreg_String wvalue ;
DATA_BLOB blob ;
WERROR result = WERR_OK ;
NTSTATUS status ;
char * str ;
/* FIXME: check format is right,
* this needs to be something like : 6.1 .7600 .16385 */
str = talloc_asprintf ( mem_ctx , " %u.%u.%u.%u " ,
( unsigned ) ( ( data > > 48 ) & 0xFFFF ) ,
( unsigned ) ( ( data > > 32 ) & 0xFFFF ) ,
( unsigned ) ( ( data > > 16 ) & 0xFFFF ) ,
( unsigned ) ( data & 0xFFFF ) ) ;
if ( ! str ) {
return WERR_NOMEM ;
}
wvalue . name = value ;
if ( ! push_reg_sz ( mem_ctx , NULL , & blob , str ) ) {
return WERR_NOMEM ;
}
status = rpccli_winreg_SetValue ( pipe_handle ,
mem_ctx ,
key_handle ,
wvalue ,
REG_SZ ,
blob . data ,
blob . length ,
& result ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 0 , ( " winreg_printer_write_date: Could not set value %s: %s \n " ,
wvalue . name , win_errstr ( result ) ) ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
result = ntstatus_to_werror ( status ) ;
}
}
return result ;
}
static WERROR winreg_printer_ver_to_dword ( const char * str , uint64_t * data )
{
unsigned int v1 , v2 , v3 , v4 ;
if ( sscanf ( str , " %u.%u.%u.%u " , & v1 , & v2 , & v3 , & v4 ) ! = 4 ) {
return WERR_INVALID_PARAMETER ;
}
* data = ( ( uint64_t ) ( v1 & 0xFFFF ) < < 48 ) +
( ( uint64_t ) ( v2 & 0xFFFF ) < < 32 ) +
( ( uint64_t ) ( v3 & 0xFFFF ) < < 16 ) +
( uint64_t ) ( v2 & 0xFFFF ) ;
return WERR_OK ;
}
2010-03-12 19:31:21 +03:00
/********************************************************************
Public winreg function for spoolss
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-04-21 14:56:39 +04:00
WERROR winreg_create_printer ( TALLOC_CTX * mem_ctx ,
struct auth_serversupplied_info * server_info ,
const char * sharename )
{
uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED ;
struct rpc_pipe_client * winreg_pipe = NULL ;
struct policy_handle hive_hnd , key_hnd ;
struct spoolss_SetPrinterInfo2 * info2 ;
struct spoolss_DeviceMode * devmode ;
struct security_descriptor * secdesc ;
struct winreg_String wkey , wkeyclass ;
const char * path ;
const char * subkeys [ ] = { " DsDriver " , " DsSpooler " , " PrinterDriverData " } ;
uint32_t i , count = ARRAY_SIZE ( subkeys ) ;
int snum = lp_servicenumber ( sharename ) ;
uint32_t info2_mask = 0 ;
WERROR result = WERR_OK ;
TALLOC_CTX * tmp_ctx ;
tmp_ctx = talloc_new ( mem_ctx ) ;
if ( tmp_ctx = = NULL ) {
return WERR_NOMEM ;
}
path = winreg_printer_data_keyname ( tmp_ctx , sharename ) ;
if ( path = = NULL ) {
TALLOC_FREE ( tmp_ctx ) ;
return WERR_NOMEM ;
}
ZERO_STRUCT ( hive_hnd ) ;
ZERO_STRUCT ( key_hnd ) ;
result = winreg_printer_openkey ( tmp_ctx ,
server_info ,
& winreg_pipe ,
path ,
" " ,
false ,
access_mask ,
& hive_hnd ,
& key_hnd ) ;
if ( W_ERROR_IS_OK ( result ) ) {
DEBUG ( 2 , ( " winreg_create_printer: Skipping, %s already exists \n " , path ) ) ;
goto done ;
} else if ( W_ERROR_EQUAL ( result , WERR_BADFILE ) ) {
DEBUG ( 2 , ( " winreg_create_printer: Creating default values in %s \n " , path ) ) ;
} else if ( ! W_ERROR_IS_OK ( result ) ) {
DEBUG ( 0 , ( " winreg_create_printer: Could not open key %s: %s \n " ,
path , win_errstr ( result ) ) ) ;
goto done ;
}
/* Create the main key */
result = winreg_printer_openkey ( tmp_ctx ,
server_info ,
& winreg_pipe ,
path ,
" " ,
true ,
access_mask ,
& hive_hnd ,
& key_hnd ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
DEBUG ( 0 , ( " winreg_create_printer_keys: Could not create key %s: %s \n " ,
path , win_errstr ( result ) ) ) ;
goto done ;
}
if ( is_valid_policy_hnd ( & key_hnd ) ) {
rpccli_winreg_CloseKey ( winreg_pipe , tmp_ctx , & key_hnd , NULL ) ;
}
/* Create subkeys */
for ( i = 0 ; i < count ; i + + ) {
NTSTATUS status ;
enum winreg_CreateAction action = REG_ACTION_NONE ;
ZERO_STRUCT ( key_hnd ) ;
ZERO_STRUCT ( wkey ) ;
wkey . name = talloc_asprintf ( tmp_ctx , " %s \\ %s " , path , subkeys [ i ] ) ;
if ( wkey . name = = NULL ) {
result = WERR_NOMEM ;
goto done ;
}
ZERO_STRUCT ( wkeyclass ) ;
wkeyclass . name = " " ;
status = rpccli_winreg_CreateKey ( winreg_pipe ,
tmp_ctx ,
& hive_hnd ,
wkey ,
wkeyclass ,
0 ,
access_mask ,
NULL ,
& key_hnd ,
& action ,
& result ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 0 , ( " winreg_create_printer_keys: Could not create key %s: %s \n " ,
wkey . name , win_errstr ( result ) ) ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
result = ntstatus_to_werror ( status ) ;
}
goto done ;
}
if ( is_valid_policy_hnd ( & key_hnd ) ) {
rpccli_winreg_CloseKey ( winreg_pipe , tmp_ctx , & key_hnd , NULL ) ;
}
}
info2 = talloc_zero ( tmp_ctx , struct spoolss_SetPrinterInfo2 ) ;
if ( info2 = = NULL ) {
result = WERR_NOMEM ;
goto done ;
}
info2 - > printername = sharename ;
info2_mask | = SPOOLSS_PRINTER_INFO_PRINTERNAME ;
info2 - > sharename = sharename ;
info2_mask | = SPOOLSS_PRINTER_INFO_SHARENAME ;
info2 - > portname = SAMBA_PRINTER_PORT_NAME ;
info2_mask | = SPOOLSS_PRINTER_INFO_PORTNAME ;
info2 - > printprocessor = " winprint " ;
info2_mask | = SPOOLSS_PRINTER_INFO_PRINTPROCESSOR ;
info2 - > datatype = " RAW " ;
info2_mask | = SPOOLSS_PRINTER_INFO_DATATYPE ;
info2 - > comment = " " ;
info2_mask | = SPOOLSS_PRINTER_INFO_COMMENT ;
info2 - > attributes = PRINTER_ATTRIBUTE_SAMBA ;
info2_mask | = SPOOLSS_PRINTER_INFO_ATTRIBUTES ;
info2 - > starttime = 0 ; /* Minutes since 12:00am GMT */
info2_mask | = SPOOLSS_PRINTER_INFO_STARTTIME ;
info2 - > untiltime = 0 ; /* Minutes since 12:00am GMT */
info2_mask | = SPOOLSS_PRINTER_INFO_UNTILTIME ;
info2 - > priority = 1 ;
info2_mask | = SPOOLSS_PRINTER_INFO_PRIORITY ;
info2 - > defaultpriority = 1 ;
info2_mask | = SPOOLSS_PRINTER_INFO_DEFAULTPRIORITY ;
/* info2->setuptime = (uint32_t) time(NULL); */
if ( lp_default_devmode ( snum ) ) {
devmode = winreg_printer_create_default_devmode ( tmp_ctx ,
info2 - > printername ) ;
if ( devmode = = NULL ) {
result = WERR_NOMEM ;
goto done ;
}
info2_mask | = SPOOLSS_PRINTER_INFO_DEVMODE ;
}
secdesc = winreg_printer_create_default_secdesc ( tmp_ctx ) ;
if ( secdesc = = NULL ) {
result = WERR_NOMEM ;
goto done ;
}
info2_mask | = SPOOLSS_PRINTER_INFO_SECDESC ;
result = winreg_update_printer ( tmp_ctx ,
server_info ,
info2_mask ,
info2 ,
devmode ,
secdesc ) ;
done :
if ( winreg_pipe ! = NULL ) {
if ( is_valid_policy_hnd ( & key_hnd ) ) {
rpccli_winreg_CloseKey ( winreg_pipe , tmp_ctx , & key_hnd , NULL ) ;
}
if ( is_valid_policy_hnd ( & hive_hnd ) ) {
rpccli_winreg_CloseKey ( winreg_pipe , tmp_ctx , & hive_hnd , NULL ) ;
}
}
talloc_free ( tmp_ctx ) ;
return result ;
}
2010-04-15 19:53:39 +04:00
WERROR winreg_update_printer ( TALLOC_CTX * mem_ctx ,
struct auth_serversupplied_info * server_info ,
uint32_t info2_mask ,
struct spoolss_SetPrinterInfo2 * info2 ,
struct spoolss_DeviceMode * devmode ,
struct security_descriptor * secdesc )
{
uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED ;
struct rpc_pipe_client * winreg_pipe = NULL ;
struct policy_handle hive_hnd , key_hnd ;
enum ndr_err_code ndr_err ;
DATA_BLOB blob ;
char * path ;
WERROR result = WERR_OK ;
TALLOC_CTX * tmp_ctx ;
tmp_ctx = talloc_new ( mem_ctx ) ;
if ( tmp_ctx = = NULL ) {
return WERR_NOMEM ;
}
path = winreg_printer_data_keyname ( tmp_ctx , info2 - > sharename ) ;
if ( path = = NULL ) {
TALLOC_FREE ( tmp_ctx ) ;
return WERR_NOMEM ;
}
ZERO_STRUCT ( hive_hnd ) ;
ZERO_STRUCT ( key_hnd ) ;
result = winreg_printer_openkey ( tmp_ctx ,
server_info ,
& winreg_pipe ,
path ,
" " ,
true ,
access_mask ,
& hive_hnd ,
& key_hnd ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
DEBUG ( 0 , ( " winreg_update_printer: Could not open key %s: %s \n " ,
path , win_errstr ( result ) ) ) ;
goto done ;
}
if ( info2_mask & SPOOLSS_PRINTER_INFO_ATTRIBUTES ) {
result = winreg_printer_write_dword ( tmp_ctx ,
winreg_pipe ,
& key_hnd ,
" Attributes " ,
info2 - > attributes ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
goto done ;
}
}
#if 0
if ( info2_mask & SPOOLSS_PRINTER_INFO_AVERAGEPPM ) {
result = winreg_printer_write_dword ( tmp_ctx ,
winreg_pipe ,
& key_hnd ,
" AveragePpm " ,
info2 - > attributes ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
goto done ;
}
}
# endif
if ( info2_mask & SPOOLSS_PRINTER_INFO_COMMENT ) {
result = winreg_printer_write_sz ( tmp_ctx ,
winreg_pipe ,
& key_hnd ,
" Description " ,
info2 - > comment ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
goto done ;
}
}
if ( info2_mask & SPOOLSS_PRINTER_INFO_DATATYPE ) {
result = winreg_printer_write_sz ( tmp_ctx ,
winreg_pipe ,
& key_hnd ,
" Datatype " ,
info2 - > datatype ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
goto done ;
}
}
if ( info2_mask & SPOOLSS_PRINTER_INFO_DEFAULTPRIORITY ) {
result = winreg_printer_write_dword ( tmp_ctx ,
winreg_pipe ,
& key_hnd ,
" Default Priority " ,
info2 - > defaultpriority ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
goto done ;
}
}
if ( info2_mask & SPOOLSS_PRINTER_INFO_DEVMODE ) {
ndr_err = ndr_push_struct_blob ( & blob , tmp_ctx , NULL , devmode ,
( ndr_push_flags_fn_t ) ndr_push_spoolss_DeviceMode ) ;
if ( ! NDR_ERR_CODE_IS_SUCCESS ( ndr_err ) ) {
DEBUG ( 0 , ( " winreg_update_printer: Failed to marshall device mode \n " ) ) ;
result = WERR_NOMEM ;
goto done ;
}
result = winreg_printer_write_binary ( tmp_ctx ,
winreg_pipe ,
& key_hnd ,
" Default DevMode " ,
blob ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
goto done ;
}
}
if ( info2_mask & SPOOLSS_PRINTER_INFO_LOCATION ) {
result = winreg_printer_write_sz ( tmp_ctx ,
winreg_pipe ,
& key_hnd ,
" Location " ,
info2 - > location ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
goto done ;
}
}
if ( info2_mask & SPOOLSS_PRINTER_INFO_PARAMETERS ) {
result = winreg_printer_write_sz ( tmp_ctx ,
winreg_pipe ,
& key_hnd ,
" Parameters " ,
info2 - > parameters ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
goto done ;
}
}
if ( info2_mask & SPOOLSS_PRINTER_INFO_PORTNAME ) {
result = winreg_printer_write_sz ( tmp_ctx ,
winreg_pipe ,
& key_hnd ,
" Port " ,
info2 - > portname ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
goto done ;
}
}
if ( info2_mask & SPOOLSS_PRINTER_INFO_PRINTERNAME ) {
/*
* in addprinter : no servername and the printer is the name
* in setprinter : servername is \ \ server
* and printer is \ \ server \ \ printer
*
* Samba manages only local printers .
* we currently don ' t support things like i
* path = \ \ other_server \ printer
*
* We only store the printername , not \ \ server \ printername
*/
const char * p = strrchr ( info2 - > printername , ' \\ ' ) ;
if ( p = = NULL ) {
p = info2 - > printername ;
} else {
p + + ;
}
result = winreg_printer_write_sz ( tmp_ctx ,
winreg_pipe ,
& key_hnd ,
" Name " ,
p ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
goto done ;
}
}
if ( info2_mask & SPOOLSS_PRINTER_INFO_PRINTPROCESSOR ) {
result = winreg_printer_write_sz ( tmp_ctx ,
winreg_pipe ,
& key_hnd ,
" Print Processor " ,
info2 - > printprocessor ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
goto done ;
}
}
if ( info2_mask & SPOOLSS_PRINTER_INFO_PRIORITY ) {
result = winreg_printer_write_dword ( tmp_ctx ,
winreg_pipe ,
& key_hnd ,
" Priority " ,
info2 - > priority ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
goto done ;
}
}
if ( info2_mask & SPOOLSS_PRINTER_INFO_SECDESC ) {
/*
* We need a security descriptor , if it isn ' t specified by
* AddPrinter { Ex } then create a default descriptor .
*/
if ( secdesc = = NULL ) {
secdesc = winreg_printer_create_default_secdesc ( tmp_ctx ) ;
}
ndr_err = ndr_push_struct_blob ( & blob , tmp_ctx , NULL , secdesc ,
( ndr_push_flags_fn_t ) ndr_push_security_descriptor ) ;
if ( ! NDR_ERR_CODE_IS_SUCCESS ( ndr_err ) ) {
DEBUG ( 0 , ( " winreg_update_printer: Failed to marshall security descriptor \n " ) ) ;
result = WERR_NOMEM ;
goto done ;
}
result = winreg_printer_write_binary ( tmp_ctx ,
winreg_pipe ,
& key_hnd ,
" Security " ,
blob ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
goto done ;
}
}
if ( info2_mask & SPOOLSS_PRINTER_INFO_SEPFILE ) {
result = winreg_printer_write_sz ( tmp_ctx ,
winreg_pipe ,
& key_hnd ,
" Separator File " ,
info2 - > sepfile ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
goto done ;
}
}
if ( info2_mask & SPOOLSS_PRINTER_INFO_SHARENAME ) {
result = winreg_printer_write_sz ( tmp_ctx ,
winreg_pipe ,
& key_hnd ,
" Share Name " ,
info2 - > sharename ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
goto done ;
}
}
if ( info2_mask & SPOOLSS_PRINTER_INFO_STARTTIME ) {
result = winreg_printer_write_dword ( tmp_ctx ,
winreg_pipe ,
& key_hnd ,
" StartTime " ,
info2 - > starttime ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
goto done ;
}
}
if ( info2_mask & SPOOLSS_PRINTER_INFO_STATUS ) {
result = winreg_printer_write_dword ( tmp_ctx ,
winreg_pipe ,
& key_hnd ,
" Status " ,
info2 - > status ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
goto done ;
}
}
if ( info2_mask & SPOOLSS_PRINTER_INFO_UNTILTIME ) {
result = winreg_printer_write_dword ( tmp_ctx ,
winreg_pipe ,
& key_hnd ,
" UntilTime " ,
info2 - > untiltime ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
goto done ;
}
}
result = winreg_printer_write_dword ( tmp_ctx ,
winreg_pipe ,
& key_hnd ,
" ChangeID " ,
winreg_printer_rev_changeid ( ) ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
goto done ;
}
result = WERR_OK ;
done :
if ( winreg_pipe ! = NULL ) {
if ( is_valid_policy_hnd ( & key_hnd ) ) {
rpccli_winreg_CloseKey ( winreg_pipe , tmp_ctx , & key_hnd , NULL ) ;
}
if ( is_valid_policy_hnd ( & hive_hnd ) ) {
rpccli_winreg_CloseKey ( winreg_pipe , tmp_ctx , & hive_hnd , NULL ) ;
}
}
TALLOC_FREE ( tmp_ctx ) ;
return result ;
}
2010-04-21 19:13:02 +04:00
WERROR winreg_get_printer ( TALLOC_CTX * mem_ctx ,
struct auth_serversupplied_info * server_info ,
const char * printer ,
struct spoolss_PrinterInfo2 * * pinfo2 )
{
struct spoolss_PrinterInfo2 * info2 ;
uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED ;
struct rpc_pipe_client * winreg_pipe = NULL ;
struct policy_handle hive_hnd , key_hnd ;
struct spoolss_PrinterEnumValues * enum_values = NULL ;
struct spoolss_PrinterEnumValues * v ;
enum ndr_err_code ndr_err ;
DATA_BLOB blob ;
uint32_t num_values = 0 ;
uint32_t i ;
char * path ;
WERROR result = WERR_OK ;
TALLOC_CTX * tmp_ctx ;
tmp_ctx = talloc_new ( mem_ctx ) ;
if ( tmp_ctx = = NULL ) {
return WERR_NOMEM ;
}
path = winreg_printer_data_keyname ( tmp_ctx , printer ) ;
if ( path = = NULL ) {
TALLOC_FREE ( tmp_ctx ) ;
return WERR_NOMEM ;
}
result = winreg_printer_openkey ( tmp_ctx ,
server_info ,
& winreg_pipe ,
path ,
" " ,
false ,
access_mask ,
& hive_hnd ,
& key_hnd ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
DEBUG ( 0 , ( " winreg_get_printer: Could not open key %s: %s \n " ,
path , win_errstr ( result ) ) ) ;
goto done ;
}
result = winreg_printer_enumvalues ( tmp_ctx ,
winreg_pipe ,
& key_hnd ,
& num_values ,
& enum_values ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
DEBUG ( 0 , ( " winreg_get_printer: Could not enumerate values in %s: %s \n " ,
path , win_errstr ( result ) ) ) ;
goto done ;
}
info2 = talloc_zero ( tmp_ctx , struct spoolss_PrinterInfo2 ) ;
if ( info2 = = NULL ) {
result = WERR_NOMEM ;
goto done ;
}
info2 - > servername = talloc_asprintf ( info2 , " \\ \\ %s " , global_myname ( ) ) ;
if ( info2 - > servername = = NULL ) {
result = WERR_NOMEM ;
goto done ;
}
info2 - > printername = EMPTY_STRING ;
info2 - > sharename = EMPTY_STRING ;
info2 - > portname = EMPTY_STRING ;
info2 - > drivername = EMPTY_STRING ;
info2 - > comment = EMPTY_STRING ;
info2 - > location = EMPTY_STRING ;
info2 - > sepfile = EMPTY_STRING ;
info2 - > printprocessor = EMPTY_STRING ;
info2 - > datatype = EMPTY_STRING ;
info2 - > parameters = EMPTY_STRING ;
for ( i = 0 ; i < num_values ; i + + ) {
v = & enum_values [ i ] ;
result = winreg_enumval_to_sz ( info2 ,
v ,
" Name " ,
& info2 - > printername ) ;
CHECK_ERROR ( result ) ;
result = winreg_enumval_to_sz ( info2 ,
v ,
" Share Name " ,
& info2 - > sharename ) ;
CHECK_ERROR ( result ) ;
result = winreg_enumval_to_sz ( info2 ,
v ,
" Port " ,
& info2 - > portname ) ;
CHECK_ERROR ( result ) ;
result = winreg_enumval_to_sz ( info2 ,
v ,
" Description " ,
& info2 - > comment ) ;
CHECK_ERROR ( result ) ;
result = winreg_enumval_to_sz ( info2 ,
v ,
" Location " ,
& info2 - > location ) ;
CHECK_ERROR ( result ) ;
result = winreg_enumval_to_sz ( info2 ,
v ,
" Separator File " ,
& info2 - > sepfile ) ;
CHECK_ERROR ( result ) ;
result = winreg_enumval_to_sz ( info2 ,
v ,
" Print Processor " ,
& info2 - > printprocessor ) ;
CHECK_ERROR ( result ) ;
result = winreg_enumval_to_sz ( info2 ,
v ,
" Datatype " ,
& info2 - > datatype ) ;
CHECK_ERROR ( result ) ;
result = winreg_enumval_to_sz ( info2 ,
v ,
" Parameters " ,
& info2 - > parameters ) ;
CHECK_ERROR ( result ) ;
result = winreg_enumval_to_dword ( info2 ,
v ,
" Attributes " ,
& info2 - > attributes ) ;
CHECK_ERROR ( result ) ;
result = winreg_enumval_to_dword ( info2 ,
v ,
" Priority " ,
& info2 - > priority ) ;
CHECK_ERROR ( result ) ;
result = winreg_enumval_to_dword ( info2 ,
v ,
" Default Priority " ,
& info2 - > defaultpriority ) ;
CHECK_ERROR ( result ) ;
result = winreg_enumval_to_dword ( info2 ,
v ,
" StartTime " ,
& info2 - > starttime ) ;
CHECK_ERROR ( result ) ;
result = winreg_enumval_to_dword ( info2 ,
v ,
" UntilTime " ,
& info2 - > untiltime ) ;
CHECK_ERROR ( result ) ;
result = winreg_enumval_to_dword ( info2 ,
v ,
" Status " ,
& info2 - > status ) ;
CHECK_ERROR ( result ) ;
result = winreg_enumval_to_dword ( info2 ,
v ,
" StartTime " ,
& info2 - > starttime ) ;
CHECK_ERROR ( result ) ;
result = winreg_enumval_to_blob ( info2 ,
v ,
" Default DevMode " ,
& blob ) ;
if ( W_ERROR_IS_OK ( result ) ) {
info2 - > devmode = talloc_zero ( mem_ctx , struct spoolss_DeviceMode ) ;
if ( info2 - > devmode = = NULL ) {
result = WERR_NOMEM ;
goto done ;
}
ndr_err = ndr_pull_struct_blob ( & blob ,
info2 ,
NULL ,
info2 - > devmode ,
( ndr_pull_flags_fn_t ) ndr_pull_spoolss_DeviceMode ) ;
if ( ! NDR_ERR_CODE_IS_SUCCESS ( ndr_err ) ) {
DEBUG ( 0 , ( " winreg_get_printer: Failed to unmarshall device mode \n " ) ) ;
result = WERR_NOMEM ;
goto done ;
}
}
CHECK_ERROR ( result ) ;
result = winreg_enumval_to_blob ( info2 ,
v ,
" Security " ,
& blob ) ;
if ( W_ERROR_IS_OK ( result ) ) {
info2 - > secdesc = talloc_zero ( mem_ctx , struct spoolss_security_descriptor ) ;
if ( info2 - > secdesc = = NULL ) {
result = WERR_NOMEM ;
goto done ;
}
ndr_err = ndr_pull_struct_blob ( & blob ,
mem_ctx ,
NULL ,
info2 - > secdesc ,
( ndr_pull_flags_fn_t ) ndr_pull_security_descriptor ) ;
if ( ! NDR_ERR_CODE_IS_SUCCESS ( ndr_err ) ) {
DEBUG ( 0 , ( " winreg_get_printer: Failed to unmarshall security descriptor \n " ) ) ;
result = WERR_NOMEM ;
goto done ;
}
}
CHECK_ERROR ( result ) ;
}
if ( ! W_ERROR_IS_OK ( result ) ) {
DEBUG ( 0 , ( " winreg_get_printer: winreg_enumval_to_TYPE() failed "
" for %s: %s \n " ,
v - > value_name ,
win_errstr ( result ) ) ) ;
goto done ;
}
if ( pinfo2 ) {
* pinfo2 = talloc_move ( mem_ctx , & info2 ) ;
}
result = WERR_OK ;
done :
if ( winreg_pipe ! = NULL ) {
if ( is_valid_policy_hnd ( & key_hnd ) ) {
rpccli_winreg_CloseKey ( winreg_pipe , tmp_ctx , & key_hnd , NULL ) ;
}
if ( is_valid_policy_hnd ( & hive_hnd ) ) {
rpccli_winreg_CloseKey ( winreg_pipe , tmp_ctx , & hive_hnd , NULL ) ;
}
}
TALLOC_FREE ( tmp_ctx ) ;
return result ;
}
2010-03-15 14:24:59 +03:00
/* Set printer data over the winreg pipe. */
2010-04-19 20:34:36 +04:00
WERROR winreg_set_printer_dataex ( TALLOC_CTX * mem_ctx ,
struct auth_serversupplied_info * server_info ,
2010-03-15 14:24:59 +03:00
const char * printer ,
const char * key ,
const char * value ,
enum winreg_Type type ,
uint8_t * data ,
uint32_t data_size )
{
uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED ;
struct rpc_pipe_client * winreg_pipe = NULL ;
struct policy_handle hive_hnd , key_hnd ;
struct winreg_String wvalue ;
2010-03-30 16:46:32 +04:00
char * path ;
2010-03-15 14:24:59 +03:00
WERROR result = WERR_OK ;
NTSTATUS status ;
TALLOC_CTX * tmp_ctx ;
2010-04-19 20:34:36 +04:00
tmp_ctx = talloc_new ( mem_ctx ) ;
2010-03-15 14:24:59 +03:00
if ( tmp_ctx = = NULL ) {
return WERR_NOMEM ;
}
2010-03-30 16:46:32 +04:00
path = winreg_printer_data_keyname ( tmp_ctx , printer ) ;
if ( path = = NULL ) {
TALLOC_FREE ( tmp_ctx ) ;
return WERR_NOMEM ;
}
2010-03-15 14:24:59 +03:00
ZERO_STRUCT ( hive_hnd ) ;
ZERO_STRUCT ( key_hnd ) ;
DEBUG ( 8 , ( " winreg_set_printer_dataex: Open printer key %s, value %s, access_mask: 0x%05x for [%s] \n " ,
key , value , access_mask , printer ) ) ;
result = winreg_printer_openkey ( tmp_ctx ,
2010-04-19 20:34:36 +04:00
server_info ,
2010-03-15 14:24:59 +03:00
& winreg_pipe ,
2010-03-30 16:46:32 +04:00
path ,
2010-03-15 14:24:59 +03:00
key ,
true ,
access_mask ,
& hive_hnd ,
& key_hnd ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
DEBUG ( 0 , ( " winreg_set_printer_dataex: Could not open key %s: %s \n " ,
key , win_errstr ( result ) ) ) ;
goto done ;
}
wvalue . name = value ;
status = rpccli_winreg_SetValue ( winreg_pipe ,
tmp_ctx ,
& key_hnd ,
wvalue ,
type ,
data ,
data_size ,
& result ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 0 , ( " winreg_set_printer_dataex: Could not set value %s: %s \n " ,
value , nt_errstr ( status ) ) ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
goto done ;
}
result = ntstatus_to_werror ( status ) ;
goto done ;
}
result = WERR_OK ;
done :
if ( winreg_pipe ! = NULL ) {
if ( is_valid_policy_hnd ( & key_hnd ) ) {
rpccli_winreg_CloseKey ( winreg_pipe , tmp_ctx , & key_hnd , NULL ) ;
}
if ( is_valid_policy_hnd ( & hive_hnd ) ) {
rpccli_winreg_CloseKey ( winreg_pipe , tmp_ctx , & hive_hnd , NULL ) ;
}
}
TALLOC_FREE ( tmp_ctx ) ;
return result ;
}
2010-03-15 14:27:51 +03:00
/* Get printer data over a winreg pipe. */
2010-04-19 20:34:36 +04:00
WERROR winreg_get_printer_dataex ( TALLOC_CTX * mem_ctx ,
struct auth_serversupplied_info * server_info ,
2010-03-15 14:27:51 +03:00
const char * printer ,
const char * key ,
const char * value ,
enum winreg_Type * type ,
uint8_t * * data ,
uint32_t * data_size )
{
uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED ;
struct rpc_pipe_client * winreg_pipe = NULL ;
struct policy_handle hive_hnd , key_hnd ;
struct winreg_String wvalue ;
enum winreg_Type type_in ;
2010-03-30 16:46:32 +04:00
char * path ;
2010-03-15 14:27:51 +03:00
uint8_t * data_in ;
uint32_t data_in_size = 0 ;
uint32_t value_len = 0 ;
WERROR result = WERR_OK ;
NTSTATUS status ;
TALLOC_CTX * tmp_ctx ;
2010-04-19 20:34:36 +04:00
tmp_ctx = talloc_new ( mem_ctx ) ;
2010-03-15 14:27:51 +03:00
if ( tmp_ctx = = NULL ) {
return WERR_NOMEM ;
}
2010-03-30 16:46:32 +04:00
path = winreg_printer_data_keyname ( tmp_ctx , printer ) ;
if ( path = = NULL ) {
TALLOC_FREE ( tmp_ctx ) ;
return WERR_NOMEM ;
}
2010-03-15 14:27:51 +03:00
ZERO_STRUCT ( hive_hnd ) ;
ZERO_STRUCT ( key_hnd ) ;
result = winreg_printer_openkey ( tmp_ctx ,
2010-04-19 20:34:36 +04:00
server_info ,
2010-03-15 14:27:51 +03:00
& winreg_pipe ,
2010-03-30 16:46:32 +04:00
path ,
2010-03-15 14:27:51 +03:00
key ,
false ,
access_mask ,
& hive_hnd ,
& key_hnd ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
DEBUG ( 0 , ( " winreg_get_printer_dataex: Could not open key %s: %s \n " ,
key , win_errstr ( result ) ) ) ;
goto done ;
}
wvalue . name = value ;
/*
* call QueryValue once with data = = NULL to get the
* needed memory size to be allocated , then allocate
* data buffer and call again .
*/
status = rpccli_winreg_QueryValue ( winreg_pipe ,
tmp_ctx ,
& key_hnd ,
& wvalue ,
& type_in ,
NULL ,
& data_in_size ,
& value_len ,
& result ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 0 , ( " winreg_get_printer_dataex: Could not query value %s: %s \n " ,
value , nt_errstr ( status ) ) ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
goto done ;
}
result = ntstatus_to_werror ( status ) ;
goto done ;
}
data_in = ( uint8_t * ) TALLOC ( tmp_ctx , data_in_size ) ;
if ( data_in = = NULL ) {
result = WERR_NOMEM ;
goto done ;
}
value_len = 0 ;
status = rpccli_winreg_QueryValue ( winreg_pipe ,
tmp_ctx ,
& key_hnd ,
& wvalue ,
& type_in ,
data_in ,
& data_in_size ,
& value_len ,
& result ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 0 , ( " winreg_get_printer_dataex: Could not query value %s: %s \n " ,
value , nt_errstr ( status ) ) ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
result = ntstatus_to_werror ( status ) ;
}
goto done ;
}
* type = type_in ;
* data_size = data_in_size ;
if ( data_in_size ) {
2010-04-19 20:34:36 +04:00
* data = talloc_move ( mem_ctx , & data_in ) ;
2010-03-15 14:27:51 +03:00
}
result = WERR_OK ;
done :
if ( winreg_pipe ! = NULL ) {
if ( is_valid_policy_hnd ( & key_hnd ) ) {
rpccli_winreg_CloseKey ( winreg_pipe , tmp_ctx , & key_hnd , NULL ) ;
}
if ( is_valid_policy_hnd ( & hive_hnd ) ) {
rpccli_winreg_CloseKey ( winreg_pipe , tmp_ctx , & hive_hnd , NULL ) ;
}
}
TALLOC_FREE ( tmp_ctx ) ;
return result ;
}
2010-03-12 19:31:21 +03:00
/* Enumerate on the values of a given key and provide the data. */
2010-04-19 20:34:36 +04:00
WERROR winreg_enum_printer_dataex ( TALLOC_CTX * mem_ctx ,
struct auth_serversupplied_info * server_info ,
2010-03-12 19:31:21 +03:00
const char * printer ,
const char * key ,
uint32_t * pnum_values ,
struct spoolss_PrinterEnumValues * * penum_values )
{
uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED ;
struct rpc_pipe_client * winreg_pipe = NULL ;
struct policy_handle hive_hnd , key_hnd ;
struct spoolss_PrinterEnumValues * enum_values = NULL ;
uint32_t num_values = 0 ;
2010-03-30 16:46:32 +04:00
char * path ;
2010-03-12 19:31:21 +03:00
WERROR result = WERR_OK ;
TALLOC_CTX * tmp_ctx ;
2010-04-19 20:34:36 +04:00
tmp_ctx = talloc_new ( mem_ctx ) ;
2010-03-12 19:31:21 +03:00
if ( tmp_ctx = = NULL ) {
return WERR_NOMEM ;
}
2010-03-30 16:46:32 +04:00
path = winreg_printer_data_keyname ( tmp_ctx , printer ) ;
if ( path = = NULL ) {
TALLOC_FREE ( tmp_ctx ) ;
return WERR_NOMEM ;
}
2010-03-12 19:31:21 +03:00
result = winreg_printer_openkey ( tmp_ctx ,
2010-04-19 20:34:36 +04:00
server_info ,
2010-03-12 19:31:21 +03:00
& winreg_pipe ,
2010-03-30 16:46:32 +04:00
path ,
2010-03-12 19:31:21 +03:00
key ,
false ,
access_mask ,
& hive_hnd ,
& key_hnd ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
DEBUG ( 0 , ( " winreg_enum_printer_dataex: Could not open key %s: %s \n " ,
key , win_errstr ( result ) ) ) ;
goto done ;
}
result = winreg_printer_enumvalues ( tmp_ctx ,
winreg_pipe ,
& key_hnd ,
& num_values ,
& enum_values ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
DEBUG ( 0 , ( " winreg_enum_printer_dataex: Could not enumerate values in %s: %s \n " ,
key , win_errstr ( result ) ) ) ;
goto done ;
}
* pnum_values = num_values ;
if ( penum_values ) {
2010-04-19 20:34:36 +04:00
* penum_values = talloc_move ( mem_ctx , & enum_values ) ;
2010-03-12 19:31:21 +03:00
}
result = WERR_OK ;
done :
if ( winreg_pipe ! = NULL ) {
if ( is_valid_policy_hnd ( & key_hnd ) ) {
rpccli_winreg_CloseKey ( winreg_pipe , tmp_ctx , & key_hnd , NULL ) ;
}
if ( is_valid_policy_hnd ( & hive_hnd ) ) {
rpccli_winreg_CloseKey ( winreg_pipe , tmp_ctx , & hive_hnd , NULL ) ;
}
}
TALLOC_FREE ( tmp_ctx ) ;
return result ;
}
2010-03-15 14:30:05 +03:00
/* Delete printer data over a winreg pipe. */
2010-04-19 20:34:36 +04:00
WERROR winreg_delete_printer_dataex ( TALLOC_CTX * mem_ctx ,
struct auth_serversupplied_info * server_info ,
2010-03-15 14:30:05 +03:00
const char * printer ,
const char * key ,
const char * value )
{
uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED ;
struct rpc_pipe_client * winreg_pipe = NULL ;
struct policy_handle hive_hnd , key_hnd ;
struct winreg_String wvalue ;
2010-03-30 16:46:32 +04:00
char * path ;
2010-03-15 14:30:05 +03:00
WERROR result = WERR_OK ;
NTSTATUS status ;
TALLOC_CTX * tmp_ctx ;
2010-04-19 20:34:36 +04:00
tmp_ctx = talloc_new ( mem_ctx ) ;
2010-03-15 14:30:05 +03:00
if ( tmp_ctx = = NULL ) {
return WERR_NOMEM ;
}
2010-03-30 16:46:32 +04:00
path = winreg_printer_data_keyname ( tmp_ctx , printer ) ;
if ( path = = NULL ) {
TALLOC_FREE ( tmp_ctx ) ;
return WERR_NOMEM ;
}
2010-03-15 14:30:05 +03:00
ZERO_STRUCT ( hive_hnd ) ;
ZERO_STRUCT ( key_hnd ) ;
result = winreg_printer_openkey ( tmp_ctx ,
2010-04-19 20:34:36 +04:00
server_info ,
2010-03-15 14:30:05 +03:00
& winreg_pipe ,
2010-03-30 16:46:32 +04:00
path ,
2010-03-15 14:30:05 +03:00
key ,
false ,
access_mask ,
& hive_hnd ,
& key_hnd ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
DEBUG ( 0 , ( " winreg_delete_printer_dataex: Could not open key %s: %s \n " ,
key , win_errstr ( result ) ) ) ;
goto done ;
}
wvalue . name = value ;
status = rpccli_winreg_DeleteValue ( winreg_pipe ,
tmp_ctx ,
& key_hnd ,
wvalue ,
& result ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 0 , ( " winreg_delete_printer_dataex: Could not delete value %s: %s \n " ,
value , nt_errstr ( status ) ) ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
goto done ;
}
result = ntstatus_to_werror ( status ) ;
goto done ;
}
result = WERR_OK ;
done :
if ( winreg_pipe ! = NULL ) {
if ( is_valid_policy_hnd ( & key_hnd ) ) {
rpccli_winreg_CloseKey ( winreg_pipe , tmp_ctx , & key_hnd , NULL ) ;
}
if ( is_valid_policy_hnd ( & hive_hnd ) ) {
rpccli_winreg_CloseKey ( winreg_pipe , tmp_ctx , & hive_hnd , NULL ) ;
}
}
TALLOC_FREE ( tmp_ctx ) ;
return result ;
}
2010-03-17 17:59:10 +03:00
/* Enumerate on the subkeys of a given key and provide the data. */
2010-04-19 20:34:36 +04:00
WERROR winreg_enum_printer_key ( TALLOC_CTX * mem_ctx ,
struct auth_serversupplied_info * server_info ,
2010-03-17 17:59:10 +03:00
const char * printer ,
const char * key ,
uint32_t * pnum_subkeys ,
const char * * * psubkeys )
{
uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED ;
struct rpc_pipe_client * winreg_pipe = NULL ;
struct policy_handle hive_hnd , key_hnd ;
2010-03-30 16:46:32 +04:00
char * path ;
2010-03-17 17:59:10 +03:00
const char * * subkeys = NULL ;
uint32_t num_subkeys = - 1 ;
WERROR result = WERR_OK ;
TALLOC_CTX * tmp_ctx ;
2010-04-19 20:34:36 +04:00
tmp_ctx = talloc_new ( mem_ctx ) ;
2010-03-17 17:59:10 +03:00
if ( tmp_ctx = = NULL ) {
return WERR_NOMEM ;
}
2010-03-30 16:46:32 +04:00
path = winreg_printer_data_keyname ( tmp_ctx , printer ) ;
if ( path = = NULL ) {
TALLOC_FREE ( tmp_ctx ) ;
return WERR_NOMEM ;
}
2010-03-17 17:59:10 +03:00
ZERO_STRUCT ( hive_hnd ) ;
ZERO_STRUCT ( key_hnd ) ;
result = winreg_printer_openkey ( tmp_ctx ,
2010-04-19 20:34:36 +04:00
server_info ,
2010-03-17 17:59:10 +03:00
& winreg_pipe ,
2010-03-30 16:46:32 +04:00
path ,
2010-03-17 17:59:10 +03:00
key ,
false ,
access_mask ,
& hive_hnd ,
& key_hnd ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
DEBUG ( 0 , ( " winreg_enum_printer_key: Could not open key %s: %s \n " ,
key , win_errstr ( result ) ) ) ;
goto done ;
}
result = winreg_printer_enumkeys ( tmp_ctx ,
winreg_pipe ,
& key_hnd ,
& num_subkeys ,
& subkeys ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
DEBUG ( 0 , ( " winreg_enum_printer_key: Could not enumerate subkeys in %s: %s \n " ,
key , win_errstr ( result ) ) ) ;
goto done ;
}
* pnum_subkeys = num_subkeys ;
if ( psubkeys ) {
2010-04-19 20:34:36 +04:00
* psubkeys = talloc_move ( mem_ctx , & subkeys ) ;
2010-03-17 17:59:10 +03:00
}
result = WERR_OK ;
done :
if ( winreg_pipe ! = NULL ) {
if ( is_valid_policy_hnd ( & key_hnd ) ) {
rpccli_winreg_CloseKey ( winreg_pipe , tmp_ctx , & key_hnd , NULL ) ;
}
if ( is_valid_policy_hnd ( & hive_hnd ) ) {
rpccli_winreg_CloseKey ( winreg_pipe , tmp_ctx , & hive_hnd , NULL ) ;
}
}
TALLOC_FREE ( tmp_ctx ) ;
return result ;
}
2010-04-06 19:01:15 +04:00
/* Delete a key with subkeys of a given printer. */
2010-04-19 20:34:36 +04:00
WERROR winreg_delete_printer_key ( TALLOC_CTX * mem_ctx ,
struct auth_serversupplied_info * server_info ,
2010-04-06 19:01:15 +04:00
const char * printer ,
const char * key )
{
uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED ;
struct rpc_pipe_client * winreg_pipe = NULL ;
struct policy_handle hive_hnd , key_hnd ;
char * keyname ;
2010-03-30 16:46:32 +04:00
char * path ;
2010-04-06 19:01:15 +04:00
WERROR result ;
TALLOC_CTX * tmp_ctx ;
2010-04-19 20:34:36 +04:00
tmp_ctx = talloc_new ( mem_ctx ) ;
2010-04-06 19:01:15 +04:00
if ( tmp_ctx = = NULL ) {
return WERR_NOMEM ;
}
2010-03-30 16:46:32 +04:00
path = winreg_printer_data_keyname ( tmp_ctx , printer ) ;
if ( path = = NULL ) {
TALLOC_FREE ( tmp_ctx ) ;
return WERR_NOMEM ;
}
2010-04-06 19:01:15 +04:00
result = winreg_printer_openkey ( tmp_ctx ,
2010-04-19 20:34:36 +04:00
server_info ,
2010-04-06 19:01:15 +04:00
& winreg_pipe ,
2010-03-30 16:46:32 +04:00
path ,
2010-04-06 19:01:15 +04:00
key ,
false ,
access_mask ,
& hive_hnd ,
& key_hnd ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
/* key doesn't exist */
if ( W_ERROR_EQUAL ( result , WERR_BADFILE ) ) {
result = WERR_OK ;
goto done ;
}
DEBUG ( 0 , ( " winreg_delete_printer_key: Could not open key %s: %s \n " ,
key , win_errstr ( result ) ) ) ;
goto done ;
}
if ( is_valid_policy_hnd ( & key_hnd ) ) {
rpccli_winreg_CloseKey ( winreg_pipe , tmp_ctx , & key_hnd , NULL ) ;
}
2010-04-23 16:45:48 +04:00
if ( key = = NULL | | key [ 0 ] = = ' \0 ' ) {
keyname = path ;
} else {
keyname = talloc_asprintf ( tmp_ctx ,
" %s \\ %s " ,
path ,
key ) ;
if ( keyname = = NULL ) {
result = WERR_NOMEM ;
goto done ;
}
2010-04-06 19:01:15 +04:00
}
result = winreg_printer_delete_subkeys ( tmp_ctx ,
winreg_pipe ,
& hive_hnd ,
access_mask ,
keyname ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
DEBUG ( 0 , ( " winreg_delete_printer_key: Could not delete key %s: %s \n " ,
key , win_errstr ( result ) ) ) ;
goto done ;
}
done :
if ( winreg_pipe ! = NULL ) {
if ( is_valid_policy_hnd ( & key_hnd ) ) {
rpccli_winreg_CloseKey ( winreg_pipe , tmp_ctx , & key_hnd , NULL ) ;
}
if ( is_valid_policy_hnd ( & hive_hnd ) ) {
rpccli_winreg_CloseKey ( winreg_pipe , tmp_ctx , & hive_hnd , NULL ) ;
}
}
TALLOC_FREE ( tmp_ctx ) ;
return result ;
}
2010-03-31 15:03:09 +04:00
2010-04-15 17:18:26 +04:00
WERROR winreg_printer_update_changeid ( TALLOC_CTX * mem_ctx ,
struct auth_serversupplied_info * server_info ,
const char * printer )
{
uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED ;
struct rpc_pipe_client * winreg_pipe = NULL ;
struct policy_handle hive_hnd , key_hnd ;
char * path ;
WERROR result ;
TALLOC_CTX * tmp_ctx ;
tmp_ctx = talloc_new ( mem_ctx ) ;
if ( tmp_ctx = = NULL ) {
return WERR_NOMEM ;
}
path = winreg_printer_data_keyname ( tmp_ctx , printer ) ;
if ( path = = NULL ) {
TALLOC_FREE ( tmp_ctx ) ;
return WERR_NOMEM ;
}
ZERO_STRUCT ( hive_hnd ) ;
ZERO_STRUCT ( key_hnd ) ;
result = winreg_printer_openkey ( tmp_ctx ,
server_info ,
& winreg_pipe ,
path ,
" " ,
false ,
access_mask ,
& hive_hnd ,
& key_hnd ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
DEBUG ( 0 , ( " winreg_printer_update_changeid: Could not open key %s: %s \n " ,
path , win_errstr ( result ) ) ) ;
goto done ;
}
result = winreg_printer_write_dword ( tmp_ctx ,
winreg_pipe ,
& key_hnd ,
" ChangeID " ,
winreg_printer_rev_changeid ( ) ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
goto done ;
}
result = WERR_OK ;
done :
if ( winreg_pipe ! = NULL ) {
if ( is_valid_policy_hnd ( & key_hnd ) ) {
rpccli_winreg_CloseKey ( winreg_pipe , tmp_ctx , & key_hnd , NULL ) ;
}
if ( is_valid_policy_hnd ( & hive_hnd ) ) {
rpccli_winreg_CloseKey ( winreg_pipe , tmp_ctx , & hive_hnd , NULL ) ;
}
}
TALLOC_FREE ( tmp_ctx ) ;
return result ;
}
2010-04-15 23:51:16 +04:00
WERROR winreg_printer_get_changeid ( TALLOC_CTX * mem_ctx ,
struct auth_serversupplied_info * server_info ,
const char * printer ,
uint32_t * pchangeid )
{
uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED ;
struct rpc_pipe_client * winreg_pipe = NULL ;
struct policy_handle hive_hnd , key_hnd ;
uint32_t changeid = 0 ;
char * path ;
WERROR result ;
TALLOC_CTX * tmp_ctx ;
tmp_ctx = talloc_new ( mem_ctx ) ;
if ( tmp_ctx = = NULL ) {
return WERR_NOMEM ;
}
path = winreg_printer_data_keyname ( tmp_ctx , printer ) ;
if ( path = = NULL ) {
TALLOC_FREE ( tmp_ctx ) ;
return WERR_NOMEM ;
}
ZERO_STRUCT ( hive_hnd ) ;
ZERO_STRUCT ( key_hnd ) ;
result = winreg_printer_openkey ( tmp_ctx ,
server_info ,
& winreg_pipe ,
path ,
" " ,
false ,
access_mask ,
& hive_hnd ,
& key_hnd ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
DEBUG ( 0 , ( " winreg_printer_get_changeid: Could not open key %s: %s \n " ,
path , win_errstr ( result ) ) ) ;
goto done ;
}
DEBUG ( 0 , ( " winreg_printer_get_changeid: get changeid from %s \n " , path ) ) ;
result = winreg_printer_query_dword ( tmp_ctx ,
winreg_pipe ,
& key_hnd ,
" ChangeID " ,
& changeid ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
goto done ;
}
if ( pchangeid ) {
* pchangeid = changeid ;
}
result = WERR_OK ;
done :
if ( winreg_pipe ! = NULL ) {
if ( is_valid_policy_hnd ( & key_hnd ) ) {
rpccli_winreg_CloseKey ( winreg_pipe , tmp_ctx , & key_hnd , NULL ) ;
}
if ( is_valid_policy_hnd ( & hive_hnd ) ) {
rpccli_winreg_CloseKey ( winreg_pipe , tmp_ctx , & hive_hnd , NULL ) ;
}
}
TALLOC_FREE ( tmp_ctx ) ;
return result ;
}
2010-03-31 15:04:04 +04:00
/*
* The special behaviour of the spoolss forms is documented at the website :
*
* Managing Win32 Printserver Forms
* http : //unixwiz.net/techtips/winspooler-forms.html
*/
2010-04-19 20:34:36 +04:00
WERROR winreg_printer_addform1 ( TALLOC_CTX * mem_ctx ,
struct auth_serversupplied_info * server_info ,
2010-03-31 15:04:04 +04:00
struct spoolss_AddFormInfo1 * form )
{
uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED ;
struct rpc_pipe_client * winreg_pipe = NULL ;
struct policy_handle hive_hnd , key_hnd ;
struct winreg_String wvalue ;
DATA_BLOB blob ;
uint32_t num_info = 0 ;
union spoolss_FormInfo * info = NULL ;
uint32_t i ;
WERROR result ;
NTSTATUS status ;
TALLOC_CTX * tmp_ctx ;
2010-04-19 20:34:36 +04:00
tmp_ctx = talloc_new ( mem_ctx ) ;
2010-03-31 15:04:04 +04:00
if ( tmp_ctx = = NULL ) {
return WERR_NOMEM ;
}
ZERO_STRUCT ( hive_hnd ) ;
ZERO_STRUCT ( key_hnd ) ;
result = winreg_printer_openkey ( tmp_ctx ,
2010-04-19 20:34:36 +04:00
server_info ,
2010-03-31 15:04:04 +04:00
& winreg_pipe ,
TOP_LEVEL_CONTROL_FORMS_KEY ,
" " ,
true ,
access_mask ,
& hive_hnd ,
& key_hnd ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
DEBUG ( 0 , ( " winreg_printer_addform1: Could not open key %s: %s \n " ,
TOP_LEVEL_CONTROL_FORMS_KEY , win_errstr ( result ) ) ) ;
goto done ;
}
2010-04-19 20:34:36 +04:00
result = winreg_printer_enumforms1 ( tmp_ctx , server_info , & num_info , & info ) ;
2010-03-31 15:04:04 +04:00
if ( ! W_ERROR_IS_OK ( result ) ) {
DEBUG ( 0 , ( " winreg_printer_addform: Could not enum keys %s: %s \n " ,
TOP_LEVEL_CONTROL_FORMS_KEY , win_errstr ( result ) ) ) ;
goto done ;
}
/* If form name already exists or is builtin return ALREADY_EXISTS */
for ( i = 0 ; i < num_info ; i + + ) {
if ( strequal ( info [ i ] . info1 . form_name , form - > form_name ) ) {
result = WERR_FILE_EXISTS ;
goto done ;
}
}
wvalue . name = form - > form_name ;
blob = data_blob_talloc ( tmp_ctx , NULL , 32 ) ;
SIVAL ( blob . data , 0 , form - > size . width ) ;
SIVAL ( blob . data , 4 , form - > size . height ) ;
SIVAL ( blob . data , 8 , form - > area . left ) ;
SIVAL ( blob . data , 12 , form - > area . top ) ;
SIVAL ( blob . data , 16 , form - > area . right ) ;
SIVAL ( blob . data , 20 , form - > area . bottom ) ;
SIVAL ( blob . data , 24 , num_info + 1 ) ; /* FIXME */
SIVAL ( blob . data , 28 , form - > flags ) ;
status = rpccli_winreg_SetValue ( winreg_pipe ,
tmp_ctx ,
& key_hnd ,
wvalue ,
REG_BINARY ,
blob . data ,
blob . length ,
& result ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 0 , ( " winreg_printer_addform1: Could not set value %s: %s \n " ,
wvalue . name , nt_errstr ( status ) ) ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
goto done ;
}
result = ntstatus_to_werror ( status ) ;
goto done ;
}
result = WERR_OK ;
done :
if ( winreg_pipe ! = NULL ) {
if ( is_valid_policy_hnd ( & key_hnd ) ) {
rpccli_winreg_CloseKey ( winreg_pipe , tmp_ctx , & key_hnd , NULL ) ;
}
if ( is_valid_policy_hnd ( & hive_hnd ) ) {
rpccli_winreg_CloseKey ( winreg_pipe , tmp_ctx , & hive_hnd , NULL ) ;
}
}
TALLOC_FREE ( info ) ;
TALLOC_FREE ( tmp_ctx ) ;
return result ;
}
2010-04-19 20:34:36 +04:00
WERROR winreg_printer_enumforms1 ( TALLOC_CTX * mem_ctx ,
struct auth_serversupplied_info * server_info ,
2010-03-31 15:03:09 +04:00
uint32_t * pnum_info ,
union spoolss_FormInfo * * pinfo )
{
uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED ;
struct rpc_pipe_client * winreg_pipe = NULL ;
struct policy_handle hive_hnd , key_hnd ;
union spoolss_FormInfo * info ;
struct spoolss_PrinterEnumValues * enum_values = NULL ;
uint32_t num_values = 0 ;
uint32_t num_builtin = ARRAY_SIZE ( builtin_forms1 ) ;
uint32_t i ;
WERROR result ;
TALLOC_CTX * tmp_ctx ;
2010-04-19 20:34:36 +04:00
tmp_ctx = talloc_new ( mem_ctx ) ;
2010-03-31 15:03:09 +04:00
if ( tmp_ctx = = NULL ) {
return WERR_NOMEM ;
}
ZERO_STRUCT ( hive_hnd ) ;
ZERO_STRUCT ( key_hnd ) ;
result = winreg_printer_openkey ( tmp_ctx ,
2010-04-19 20:34:36 +04:00
server_info ,
2010-03-31 15:03:09 +04:00
& winreg_pipe ,
TOP_LEVEL_CONTROL_FORMS_KEY ,
" " ,
true ,
access_mask ,
& hive_hnd ,
& key_hnd ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
/* key doesn't exist */
if ( W_ERROR_EQUAL ( result , WERR_BADFILE ) ) {
result = WERR_OK ;
goto done ;
}
DEBUG ( 0 , ( " winreg_printer_enumforms1: Could not open key %s: %s \n " ,
TOP_LEVEL_CONTROL_FORMS_KEY , win_errstr ( result ) ) ) ;
goto done ;
}
result = winreg_printer_enumvalues ( tmp_ctx ,
winreg_pipe ,
& key_hnd ,
& num_values ,
& enum_values ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
DEBUG ( 0 , ( " winreg_printer_enumforms1: Could not enumerate values in %s: %s \n " ,
TOP_LEVEL_CONTROL_FORMS_KEY , win_errstr ( result ) ) ) ;
goto done ;
}
info = TALLOC_ARRAY ( tmp_ctx , union spoolss_FormInfo , num_builtin + num_values ) ;
if ( info = = NULL ) {
result = WERR_NOMEM ;
goto done ;
}
/* Enumerate BUILTIN forms */
for ( i = 0 ; i < num_builtin ; i + + ) {
info [ i ] . info1 = builtin_forms1 [ i ] ;
}
/* Enumerate registry forms */
for ( i = 0 ; i < num_values ; i + + ) {
union spoolss_FormInfo val ;
if ( enum_values [ i ] . type ! = REG_BINARY | |
enum_values [ i ] . data_length ! = 32 ) {
continue ;
}
val . info1 . form_name = talloc_strdup ( info , enum_values [ i ] . value_name ) ;
if ( val . info1 . form_name = = NULL ) {
result = WERR_NOMEM ;
goto done ;
}
val . info1 . size . width = IVAL ( enum_values [ i ] . data - > data , 0 ) ;
val . info1 . size . height = IVAL ( enum_values [ i ] . data - > data , 4 ) ;
val . info1 . area . left = IVAL ( enum_values [ i ] . data - > data , 8 ) ;
val . info1 . area . top = IVAL ( enum_values [ i ] . data - > data , 12 ) ;
val . info1 . area . right = IVAL ( enum_values [ i ] . data - > data , 16 ) ;
val . info1 . area . bottom = IVAL ( enum_values [ i ] . data - > data , 20 ) ;
/* skip form index IVAL(enum_values[i].data->data, 24)));*/
val . info1 . flags = IVAL ( enum_values [ i ] . data - > data , 28 ) ;
info [ i + num_builtin ] = val ;
}
* pnum_info = num_builtin + num_values ;
if ( pinfo ) {
2010-04-19 20:34:36 +04:00
* pinfo = talloc_move ( mem_ctx , & info ) ;
2010-03-31 15:03:09 +04:00
}
done :
if ( winreg_pipe ! = NULL ) {
if ( is_valid_policy_hnd ( & key_hnd ) ) {
rpccli_winreg_CloseKey ( winreg_pipe , tmp_ctx , & key_hnd , NULL ) ;
}
if ( is_valid_policy_hnd ( & hive_hnd ) ) {
rpccli_winreg_CloseKey ( winreg_pipe , tmp_ctx , & hive_hnd , NULL ) ;
}
}
TALLOC_FREE ( enum_values ) ;
TALLOC_FREE ( tmp_ctx ) ;
return result ;
}
2010-03-31 17:31:21 +04:00
2010-04-19 20:34:36 +04:00
WERROR winreg_printer_deleteform1 ( TALLOC_CTX * mem_ctx ,
struct auth_serversupplied_info * server_info ,
2010-03-31 17:31:21 +04:00
const char * form_name )
{
uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED ;
struct rpc_pipe_client * winreg_pipe = NULL ;
struct policy_handle hive_hnd , key_hnd ;
struct winreg_String wvalue ;
uint32_t num_builtin = ARRAY_SIZE ( builtin_forms1 ) ;
uint32_t i ;
WERROR result = WERR_OK ;
NTSTATUS status ;
TALLOC_CTX * tmp_ctx ;
for ( i = 0 ; i < num_builtin ; i + + ) {
if ( strequal ( builtin_forms1 [ i ] . form_name , form_name ) ) {
return WERR_INVALID_PARAMETER ;
}
}
2010-04-19 20:34:36 +04:00
tmp_ctx = talloc_new ( mem_ctx ) ;
2010-03-31 17:31:21 +04:00
if ( tmp_ctx = = NULL ) {
return WERR_NOMEM ;
}
ZERO_STRUCT ( hive_hnd ) ;
ZERO_STRUCT ( key_hnd ) ;
result = winreg_printer_openkey ( tmp_ctx ,
2010-04-19 20:34:36 +04:00
server_info ,
2010-03-31 17:31:21 +04:00
& winreg_pipe ,
TOP_LEVEL_CONTROL_FORMS_KEY ,
" " ,
false ,
access_mask ,
& hive_hnd ,
& key_hnd ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
DEBUG ( 0 , ( " winreg_printer_deleteform1: Could not open key %s: %s \n " ,
TOP_LEVEL_CONTROL_FORMS_KEY , win_errstr ( result ) ) ) ;
if ( W_ERROR_EQUAL ( result , WERR_BADFILE ) ) {
result = WERR_INVALID_FORM_NAME ;
}
goto done ;
}
wvalue . name = form_name ;
status = rpccli_winreg_DeleteValue ( winreg_pipe ,
tmp_ctx ,
& key_hnd ,
wvalue ,
& result ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2010-04-09 11:26:24 +04:00
/* If the value doesn't exist, return WERR_INVALID_FORM_NAME */
if ( W_ERROR_EQUAL ( result , WERR_BADFILE ) ) {
result = WERR_INVALID_FORM_NAME ;
goto done ;
}
2010-03-31 17:31:21 +04:00
DEBUG ( 0 , ( " winreg_printer_delteform1: Could not delete value %s: %s \n " ,
wvalue . name , nt_errstr ( status ) ) ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
goto done ;
}
result = ntstatus_to_werror ( status ) ;
goto done ;
}
result = WERR_OK ;
done :
if ( winreg_pipe ! = NULL ) {
if ( is_valid_policy_hnd ( & key_hnd ) ) {
rpccli_winreg_CloseKey ( winreg_pipe , tmp_ctx , & key_hnd , NULL ) ;
}
if ( is_valid_policy_hnd ( & hive_hnd ) ) {
rpccli_winreg_CloseKey ( winreg_pipe , tmp_ctx , & hive_hnd , NULL ) ;
}
}
TALLOC_FREE ( tmp_ctx ) ;
return result ;
}
2010-04-01 13:51:59 +04:00
2010-04-19 20:34:36 +04:00
WERROR winreg_printer_setform1 ( TALLOC_CTX * mem_ctx ,
struct auth_serversupplied_info * server_info ,
2010-04-01 13:51:59 +04:00
const char * form_name ,
struct spoolss_AddFormInfo1 * form )
{
uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED ;
struct rpc_pipe_client * winreg_pipe = NULL ;
struct policy_handle hive_hnd , key_hnd ;
struct winreg_String wvalue ;
DATA_BLOB blob ;
uint32_t num_builtin = ARRAY_SIZE ( builtin_forms1 ) ;
uint32_t i ;
WERROR result ;
NTSTATUS status ;
2010-04-09 20:44:19 +04:00
TALLOC_CTX * tmp_ctx = NULL ;
2010-04-01 13:51:59 +04:00
for ( i = 0 ; i < num_builtin ; i + + ) {
if ( strequal ( builtin_forms1 [ i ] . form_name , form - > form_name ) ) {
result = WERR_INVALID_PARAM ;
goto done ;
}
}
2010-04-19 20:34:36 +04:00
tmp_ctx = talloc_new ( mem_ctx ) ;
2010-04-01 13:51:59 +04:00
if ( tmp_ctx = = NULL ) {
return WERR_NOMEM ;
}
ZERO_STRUCT ( hive_hnd ) ;
ZERO_STRUCT ( key_hnd ) ;
result = winreg_printer_openkey ( tmp_ctx ,
2010-04-19 20:34:36 +04:00
server_info ,
2010-04-01 13:51:59 +04:00
& winreg_pipe ,
TOP_LEVEL_CONTROL_FORMS_KEY ,
" " ,
true ,
access_mask ,
& hive_hnd ,
& key_hnd ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
DEBUG ( 0 , ( " winreg_printer_setform1: Could not open key %s: %s \n " ,
TOP_LEVEL_CONTROL_FORMS_KEY , win_errstr ( result ) ) ) ;
goto done ;
}
/* If form_name != form->form_name then we renamed the form */
if ( strequal ( form_name , form - > form_name ) ) {
2010-04-19 20:34:36 +04:00
result = winreg_printer_deleteform1 ( tmp_ctx , server_info , form_name ) ;
2010-04-01 13:51:59 +04:00
if ( ! W_ERROR_IS_OK ( result ) ) {
DEBUG ( 0 , ( " winreg_printer_setform1: Could not open key %s: %s \n " ,
TOP_LEVEL_CONTROL_FORMS_KEY , win_errstr ( result ) ) ) ;
goto done ;
}
}
wvalue . name = form - > form_name ;
blob = data_blob_talloc ( tmp_ctx , NULL , 32 ) ;
SIVAL ( blob . data , 0 , form - > size . width ) ;
SIVAL ( blob . data , 4 , form - > size . height ) ;
SIVAL ( blob . data , 8 , form - > area . left ) ;
SIVAL ( blob . data , 12 , form - > area . top ) ;
SIVAL ( blob . data , 16 , form - > area . right ) ;
SIVAL ( blob . data , 20 , form - > area . bottom ) ;
SIVAL ( blob . data , 24 , 42 ) ;
SIVAL ( blob . data , 28 , form - > flags ) ;
status = rpccli_winreg_SetValue ( winreg_pipe ,
tmp_ctx ,
& key_hnd ,
wvalue ,
REG_BINARY ,
blob . data ,
blob . length ,
& result ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 0 , ( " winreg_printer_setform1: Could not set value %s: %s \n " ,
wvalue . name , nt_errstr ( status ) ) ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
goto done ;
}
result = ntstatus_to_werror ( status ) ;
goto done ;
}
result = WERR_OK ;
done :
if ( winreg_pipe ! = NULL ) {
if ( is_valid_policy_hnd ( & key_hnd ) ) {
rpccli_winreg_CloseKey ( winreg_pipe , tmp_ctx , & key_hnd , NULL ) ;
}
if ( is_valid_policy_hnd ( & hive_hnd ) ) {
rpccli_winreg_CloseKey ( winreg_pipe , tmp_ctx , & hive_hnd , NULL ) ;
}
}
TALLOC_FREE ( tmp_ctx ) ;
return result ;
}
2010-04-01 14:45:58 +04:00
2010-04-19 20:34:36 +04:00
WERROR winreg_printer_getform1 ( TALLOC_CTX * mem_ctx ,
struct auth_serversupplied_info * server_info ,
2010-04-01 14:45:58 +04:00
const char * form_name ,
struct spoolss_FormInfo1 * r )
{
uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED ;
struct rpc_pipe_client * winreg_pipe = NULL ;
struct policy_handle hive_hnd , key_hnd ;
struct winreg_String wvalue ;
enum winreg_Type type_in ;
uint8_t * data_in ;
uint32_t data_in_size = 0 ;
uint32_t value_len = 0 ;
uint32_t num_builtin = ARRAY_SIZE ( builtin_forms1 ) ;
uint32_t i ;
WERROR result ;
NTSTATUS status ;
TALLOC_CTX * tmp_ctx ;
/* check builtin forms first */
for ( i = 0 ; i < num_builtin ; i + + ) {
if ( strequal ( builtin_forms1 [ i ] . form_name , form_name ) ) {
* r = builtin_forms1 [ i ] ;
return WERR_OK ;
}
}
2010-04-19 20:34:36 +04:00
tmp_ctx = talloc_new ( mem_ctx ) ;
2010-04-01 14:45:58 +04:00
if ( tmp_ctx = = NULL ) {
return WERR_NOMEM ;
}
ZERO_STRUCT ( hive_hnd ) ;
ZERO_STRUCT ( key_hnd ) ;
result = winreg_printer_openkey ( tmp_ctx ,
2010-04-19 20:34:36 +04:00
server_info ,
2010-04-01 14:45:58 +04:00
& winreg_pipe ,
TOP_LEVEL_CONTROL_FORMS_KEY ,
" " ,
true ,
access_mask ,
& hive_hnd ,
& key_hnd ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
DEBUG ( 0 , ( " winreg_printer_getform1: Could not open key %s: %s \n " ,
TOP_LEVEL_CONTROL_FORMS_KEY , win_errstr ( result ) ) ) ;
goto done ;
}
wvalue . name = form_name ;
/*
* call QueryValue once with data = = NULL to get the
* needed memory size to be allocated , then allocate
* data buffer and call again .
*/
status = rpccli_winreg_QueryValue ( winreg_pipe ,
tmp_ctx ,
& key_hnd ,
& wvalue ,
& type_in ,
NULL ,
& data_in_size ,
& value_len ,
& result ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 0 , ( " winreg_printer_getform1: Could not query value %s: %s \n " ,
wvalue . name , nt_errstr ( status ) ) ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
goto done ;
}
result = ntstatus_to_werror ( status ) ;
goto done ;
}
data_in = ( uint8_t * ) TALLOC ( tmp_ctx , data_in_size ) ;
if ( data_in = = NULL ) {
result = WERR_NOMEM ;
goto done ;
}
value_len = 0 ;
status = rpccli_winreg_QueryValue ( winreg_pipe ,
tmp_ctx ,
& key_hnd ,
& wvalue ,
& type_in ,
data_in ,
& data_in_size ,
& value_len ,
& result ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 0 , ( " winreg_printer_getform1: Could not query value %s: %s \n " ,
wvalue . name , nt_errstr ( status ) ) ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
goto done ;
}
result = ntstatus_to_werror ( status ) ;
goto done ;
}
2010-04-19 20:34:36 +04:00
r - > form_name = talloc_strdup ( mem_ctx , form_name ) ;
2010-04-01 14:45:58 +04:00
if ( r - > form_name = = NULL ) {
result = WERR_NOMEM ;
goto done ;
}
r - > size . width = IVAL ( data_in , 0 ) ;
r - > size . height = IVAL ( data_in , 4 ) ;
r - > area . left = IVAL ( data_in , 8 ) ;
r - > area . top = IVAL ( data_in , 12 ) ;
r - > area . right = IVAL ( data_in , 16 ) ;
r - > area . bottom = IVAL ( data_in , 20 ) ;
/* skip index IVAL(data_in, 24)));*/
r - > flags = IVAL ( data_in , 28 ) ;
result = WERR_OK ;
done :
if ( winreg_pipe ! = NULL ) {
if ( is_valid_policy_hnd ( & key_hnd ) ) {
rpccli_winreg_CloseKey ( winreg_pipe , tmp_ctx , & key_hnd , NULL ) ;
}
if ( is_valid_policy_hnd ( & hive_hnd ) ) {
rpccli_winreg_CloseKey ( winreg_pipe , tmp_ctx , & hive_hnd , NULL ) ;
}
}
TALLOC_FREE ( tmp_ctx ) ;
return result ;
}
2010-04-21 17:58:51 +04:00
2010-04-21 17:37:08 +04:00
WERROR winreg_add_driver ( TALLOC_CTX * mem_ctx ,
struct auth_serversupplied_info * server_info ,
struct spoolss_AddDriverInfoCtr * r ,
const char * * driver_name ,
uint32_t * driver_version )
{
uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED ;
struct rpc_pipe_client * winreg_pipe = NULL ;
struct policy_handle hive_hnd , key_hnd ;
struct spoolss_DriverInfo8 info8 ;
TALLOC_CTX * tmp_ctx ;
WERROR result ;
ZERO_STRUCT ( hive_hnd ) ;
ZERO_STRUCT ( key_hnd ) ;
ZERO_STRUCT ( info8 ) ;
if ( ! driver_info_ctr_to_info8 ( r , & info8 ) ) {
result = WERR_INVALID_PARAMETER ;
goto done ;
}
tmp_ctx = talloc_new ( mem_ctx ) ;
if ( tmp_ctx = = NULL ) {
return WERR_NOMEM ;
}
result = winreg_printer_opendriver ( tmp_ctx ,
server_info ,
info8 . driver_name ,
info8 . architecture ,
info8 . version ,
access_mask , true ,
& winreg_pipe ,
& hive_hnd ,
& key_hnd ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
DEBUG ( 0 , ( " winreg_add_driver: "
" Could not open driver key (%s,%s,%d): %s \n " ,
info8 . driver_name , info8 . architecture ,
info8 . version , win_errstr ( result ) ) ) ;
goto done ;
}
/* TODO: "Attributes" ? */
result = winreg_printer_write_dword ( tmp_ctx , winreg_pipe ,
& key_hnd , " Version " ,
info8 . version ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
goto done ;
}
result = winreg_printer_write_sz ( tmp_ctx , winreg_pipe ,
& key_hnd , " Driver " ,
info8 . driver_path ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
goto done ;
}
result = winreg_printer_write_sz ( tmp_ctx , winreg_pipe ,
& key_hnd , " Data File " ,
info8 . data_file ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
goto done ;
}
result = winreg_printer_write_sz ( tmp_ctx , winreg_pipe ,
& key_hnd , " Configuration File " ,
info8 . config_file ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
goto done ;
}
result = winreg_printer_write_sz ( tmp_ctx , winreg_pipe ,
& key_hnd , " Help File " ,
info8 . help_file ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
goto done ;
}
result = winreg_printer_write_multi_sz ( tmp_ctx , winreg_pipe ,
& key_hnd , " Dependent Files " ,
info8 . dependent_files ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
goto done ;
}
result = winreg_printer_write_sz ( tmp_ctx , winreg_pipe ,
& key_hnd , " Monitor " ,
info8 . monitor_name ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
goto done ;
}
result = winreg_printer_write_sz ( tmp_ctx , winreg_pipe ,
& key_hnd , " Datatype " ,
info8 . default_datatype ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
goto done ;
}
result = winreg_printer_write_multi_sz ( tmp_ctx , winreg_pipe ,
& key_hnd , " Previous Names " ,
info8 . previous_names ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
goto done ;
}
result = winreg_printer_write_date ( tmp_ctx , winreg_pipe ,
& key_hnd , " DriverDate " ,
info8 . driver_date ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
goto done ;
}
result = winreg_printer_write_ver ( tmp_ctx , winreg_pipe ,
& key_hnd , " DriverVersion " ,
info8 . driver_version ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
goto done ;
}
result = winreg_printer_write_sz ( tmp_ctx , winreg_pipe ,
& key_hnd , " Manufacturer " ,
info8 . manufacturer_name ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
goto done ;
}
result = winreg_printer_write_sz ( tmp_ctx , winreg_pipe ,
& key_hnd , " OEM URL " ,
info8 . manufacturer_url ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
goto done ;
}
result = winreg_printer_write_sz ( tmp_ctx , winreg_pipe ,
& key_hnd , " HardwareID " ,
info8 . hardware_id ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
goto done ;
}
result = winreg_printer_write_sz ( tmp_ctx , winreg_pipe ,
& key_hnd , " Provider " ,
info8 . provider ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
goto done ;
}
result = winreg_printer_write_sz ( tmp_ctx , winreg_pipe ,
& key_hnd , " Print Processor " ,
info8 . print_processor ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
goto done ;
}
result = winreg_printer_write_sz ( tmp_ctx , winreg_pipe ,
& key_hnd , " VendorSetup " ,
info8 . vendor_setup ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
goto done ;
}
result = winreg_printer_write_multi_sz ( tmp_ctx , winreg_pipe ,
& key_hnd , " Color Profiles " ,
info8 . color_profiles ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
goto done ;
}
result = winreg_printer_write_sz ( tmp_ctx , winreg_pipe ,
& key_hnd , " InfPath " ,
info8 . inf_path ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
goto done ;
}
result = winreg_printer_write_dword ( tmp_ctx , winreg_pipe , & key_hnd ,
" PrinterDriverAttributes " ,
info8 . printer_driver_attributes ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
goto done ;
}
result = winreg_printer_write_multi_sz ( tmp_ctx , winreg_pipe ,
& key_hnd , " CoreDependencies " ,
info8 . core_driver_dependencies ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
goto done ;
}
result = winreg_printer_write_date ( tmp_ctx , winreg_pipe ,
& key_hnd , " MinInboxDriverVerDate " ,
info8 . min_inbox_driver_ver_date ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
goto done ;
}
result = winreg_printer_write_ver ( tmp_ctx , winreg_pipe , & key_hnd ,
" MinInboxDriverVerVersion " ,
info8 . min_inbox_driver_ver_version ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
goto done ;
}
* driver_name = info8 . driver_name ;
* driver_version = info8 . version ;
result = WERR_OK ;
done :
if ( winreg_pipe ! = NULL ) {
if ( is_valid_policy_hnd ( & key_hnd ) ) {
rpccli_winreg_CloseKey ( winreg_pipe , tmp_ctx , & key_hnd , NULL ) ;
}
if ( is_valid_policy_hnd ( & hive_hnd ) ) {
rpccli_winreg_CloseKey ( winreg_pipe , tmp_ctx , & hive_hnd , NULL ) ;
}
}
TALLOC_FREE ( tmp_ctx ) ;
return result ;
}
2010-04-21 17:38:39 +04:00
WERROR winreg_get_driver ( TALLOC_CTX * mem_ctx ,
struct auth_serversupplied_info * server_info ,
const char * architecture ,
const char * driver_name ,
uint32_t driver_version ,
struct spoolss_DriverInfo8 * * _info8 )
{
uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED ;
struct rpc_pipe_client * winreg_pipe = NULL ;
struct policy_handle hive_hnd , key_hnd ;
struct spoolss_DriverInfo8 i8 , * info8 ;
struct spoolss_PrinterEnumValues * enum_values = NULL ;
struct spoolss_PrinterEnumValues * v ;
uint32_t num_values = 0 ;
TALLOC_CTX * tmp_ctx ;
WERROR result ;
uint32_t i ;
ZERO_STRUCT ( hive_hnd ) ;
ZERO_STRUCT ( key_hnd ) ;
ZERO_STRUCT ( i8 ) ;
tmp_ctx = talloc_new ( mem_ctx ) ;
if ( tmp_ctx = = NULL ) {
return WERR_NOMEM ;
}
if ( driver_version = = DRIVER_ANY_VERSION ) {
/* look for Win2k first and then for NT4 */
result = winreg_printer_opendriver ( tmp_ctx ,
server_info ,
driver_name ,
architecture ,
3 ,
access_mask , false ,
& winreg_pipe ,
& hive_hnd ,
& key_hnd ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
result = winreg_printer_opendriver ( tmp_ctx ,
server_info ,
driver_name ,
architecture ,
2 ,
access_mask , false ,
& winreg_pipe ,
& hive_hnd ,
& key_hnd ) ;
}
} else {
/* ok normal case */
result = winreg_printer_opendriver ( tmp_ctx ,
server_info ,
driver_name ,
architecture ,
driver_version ,
access_mask , false ,
& winreg_pipe ,
& hive_hnd ,
& key_hnd ) ;
}
if ( ! W_ERROR_IS_OK ( result ) ) {
DEBUG ( 5 , ( " winreg_get_driver: "
" Could not open driver key (%s,%s,%d): %s \n " ,
driver_name , architecture ,
driver_version , win_errstr ( result ) ) ) ;
goto done ;
}
result = winreg_printer_enumvalues ( tmp_ctx ,
winreg_pipe ,
& key_hnd ,
& num_values ,
& enum_values ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
DEBUG ( 0 , ( " winreg_get_driver: "
" Could not enumerate values for (%s,%s,%d): %s \n " ,
driver_name , architecture ,
driver_version , win_errstr ( result ) ) ) ;
goto done ;
}
info8 = talloc_zero ( tmp_ctx , struct spoolss_DriverInfo8 ) ;
if ( ! info8 ) {
result = WERR_NOMEM ;
goto done ;
}
result = WERR_OK ;
for ( i = 0 ; i < num_values ; i + + ) {
const char * tmp_str ;
v = & enum_values [ i ] ;
# define CHECK_ERROR(result) \
if ( W_ERROR_IS_OK ( result ) ) continue ; \
if ( W_ERROR_EQUAL ( result , WERR_NOT_FOUND ) ) result = WERR_OK ; \
if ( ! W_ERROR_IS_OK ( result ) ) break
result = winreg_enumval_to_dword ( info8 , v ,
" Version " ,
& info8 - > version ) ;
CHECK_ERROR ( result ) ;
result = winreg_enumval_to_sz ( info8 , v ,
" Driver " ,
& info8 - > driver_path ) ;
CHECK_ERROR ( result ) ;
result = winreg_enumval_to_sz ( info8 , v ,
" Data File " ,
& info8 - > data_file ) ;
CHECK_ERROR ( result ) ;
result = winreg_enumval_to_sz ( info8 , v ,
" Configuration File " ,
& info8 - > config_file ) ;
CHECK_ERROR ( result ) ;
result = winreg_enumval_to_sz ( info8 , v ,
" Help File " ,
& info8 - > help_file ) ;
CHECK_ERROR ( result ) ;
result = winreg_enumval_to_multi_sz ( info8 , v ,
" Dependent Files " ,
& info8 - > dependent_files ) ;
CHECK_ERROR ( result ) ;
result = winreg_enumval_to_sz ( info8 , v ,
" Monitor " ,
& info8 - > monitor_name ) ;
CHECK_ERROR ( result ) ;
result = winreg_enumval_to_sz ( info8 , v ,
" Datatype " ,
& info8 - > default_datatype ) ;
CHECK_ERROR ( result ) ;
result = winreg_enumval_to_multi_sz ( info8 , v ,
" Previous Names " ,
& info8 - > previous_names ) ;
CHECK_ERROR ( result ) ;
result = winreg_enumval_to_sz ( info8 , v ,
" DriverDate " ,
& tmp_str ) ;
if ( W_ERROR_IS_OK ( result ) ) {
result = winreg_printer_date_to_NTTIME ( tmp_str ,
& info8 - > driver_date ) ;
}
CHECK_ERROR ( result ) ;
result = winreg_enumval_to_sz ( info8 , v ,
" DriverVersion " ,
& tmp_str ) ;
if ( W_ERROR_IS_OK ( result ) ) {
result = winreg_printer_ver_to_dword ( tmp_str ,
& info8 - > driver_version ) ;
}
CHECK_ERROR ( result ) ;
result = winreg_enumval_to_sz ( info8 , v ,
" Manufacturer " ,
& info8 - > manufacturer_name ) ;
CHECK_ERROR ( result ) ;
result = winreg_enumval_to_sz ( info8 , v ,
" OEM URL " ,
& info8 - > manufacturer_url ) ;
CHECK_ERROR ( result ) ;
result = winreg_enumval_to_sz ( info8 , v ,
" HardwareID " ,
& info8 - > hardware_id ) ;
CHECK_ERROR ( result ) ;
result = winreg_enumval_to_sz ( info8 , v ,
" Provider " ,
& info8 - > provider ) ;
CHECK_ERROR ( result ) ;
result = winreg_enumval_to_sz ( info8 , v ,
" Print Processor " ,
& info8 - > print_processor ) ;
CHECK_ERROR ( result ) ;
result = winreg_enumval_to_sz ( info8 , v ,
" VendorSetup " ,
& info8 - > vendor_setup ) ;
CHECK_ERROR ( result ) ;
result = winreg_enumval_to_multi_sz ( info8 , v ,
" Color Profiles " ,
& info8 - > color_profiles ) ;
CHECK_ERROR ( result ) ;
result = winreg_enumval_to_sz ( info8 , v ,
" InfPath " ,
& info8 - > inf_path ) ;
CHECK_ERROR ( result ) ;
result = winreg_enumval_to_dword ( info8 , v ,
" PrinterDriverAttributes " ,
& info8 - > printer_driver_attributes ) ;
CHECK_ERROR ( result ) ;
result = winreg_enumval_to_multi_sz ( info8 , v ,
" CoreDependencies " ,
& info8 - > core_driver_dependencies ) ;
CHECK_ERROR ( result ) ;
result = winreg_enumval_to_sz ( info8 , v ,
" MinInboxDriverVerDate " ,
& tmp_str ) ;
if ( W_ERROR_IS_OK ( result ) ) {
result = winreg_printer_date_to_NTTIME ( tmp_str ,
& info8 - > min_inbox_driver_ver_date ) ;
}
CHECK_ERROR ( result ) ;
result = winreg_enumval_to_sz ( info8 , v ,
" MinInboxDriverVerVersion " ,
& tmp_str ) ;
if ( W_ERROR_IS_OK ( result ) ) {
result = winreg_printer_ver_to_dword ( tmp_str ,
& info8 - > min_inbox_driver_ver_version ) ;
}
CHECK_ERROR ( result ) ;
}
if ( ! W_ERROR_IS_OK ( result ) ) {
DEBUG ( 0 , ( " winreg_enumval_to_TYPE() failed "
" for %s: %s \n " , v - > value_name ,
win_errstr ( result ) ) ) ;
goto done ;
}
* _info8 = talloc_steal ( mem_ctx , info8 ) ;
result = WERR_OK ;
done :
if ( winreg_pipe ! = NULL ) {
if ( is_valid_policy_hnd ( & key_hnd ) ) {
rpccli_winreg_CloseKey ( winreg_pipe , tmp_ctx , & key_hnd , NULL ) ;
}
if ( is_valid_policy_hnd ( & hive_hnd ) ) {
rpccli_winreg_CloseKey ( winreg_pipe , tmp_ctx , & hive_hnd , NULL ) ;
}
}
TALLOC_FREE ( tmp_ctx ) ;
return result ;
}
2010-04-20 05:01:38 +04:00
WERROR winreg_del_driver ( TALLOC_CTX * mem_ctx ,
struct auth_serversupplied_info * server_info ,
struct spoolss_DriverInfo8 * info8 ,
uint32_t version )
{
uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED ;
struct rpc_pipe_client * winreg_pipe = NULL ;
struct policy_handle hive_hnd , key_hnd ;
TALLOC_CTX * tmp_ctx ;
char * key_name ;
WERROR result ;
ZERO_STRUCT ( hive_hnd ) ;
ZERO_STRUCT ( key_hnd ) ;
tmp_ctx = talloc_new ( mem_ctx ) ;
if ( tmp_ctx = = NULL ) {
return WERR_NOMEM ;
}
/* test that the key exists */
result = winreg_printer_opendriver ( tmp_ctx ,
server_info ,
info8 - > driver_name ,
info8 - > architecture ,
version ,
access_mask , false ,
& winreg_pipe ,
& hive_hnd ,
& key_hnd ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
/* key doesn't exist */
if ( W_ERROR_EQUAL ( result , WERR_BADFILE ) ) {
result = WERR_OK ;
goto done ;
}
DEBUG ( 5 , ( " winreg_del_driver: "
" Could not open driver (%s,%s,%u): %s \n " ,
info8 - > driver_name , info8 - > architecture ,
version , win_errstr ( result ) ) ) ;
goto done ;
}
if ( is_valid_policy_hnd ( & key_hnd ) ) {
rpccli_winreg_CloseKey ( winreg_pipe , tmp_ctx , & key_hnd , NULL ) ;
}
key_name = talloc_asprintf ( tmp_ctx ,
" %s \\ Environments \\ %s \\ Drivers \\ Version-%u " ,
TOP_LEVEL_CONTROL_KEY ,
info8 - > architecture , version ) ;
if ( key_name = = NULL ) {
result = WERR_NOMEM ;
goto done ;
}
result = winreg_printer_delete_subkeys ( tmp_ctx ,
winreg_pipe ,
& hive_hnd ,
access_mask ,
key_name ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
DEBUG ( 0 , ( " winreg_del_driver: "
" Could not open driver (%s,%s,%u): %s \n " ,
info8 - > driver_name , info8 - > architecture ,
version , win_errstr ( result ) ) ) ;
goto done ;
}
result = WERR_OK ;
done :
if ( winreg_pipe ! = NULL ) {
if ( is_valid_policy_hnd ( & key_hnd ) ) {
rpccli_winreg_CloseKey ( winreg_pipe , tmp_ctx , & key_hnd , NULL ) ;
}
if ( is_valid_policy_hnd ( & hive_hnd ) ) {
rpccli_winreg_CloseKey ( winreg_pipe , tmp_ctx , & hive_hnd , NULL ) ;
}
}
TALLOC_FREE ( tmp_ctx ) ;
return result ;
}
2010-04-20 05:50:52 +04:00
WERROR winreg_get_driver_list ( TALLOC_CTX * mem_ctx ,
struct auth_serversupplied_info * server_info ,
const char * architecture ,
uint32_t version ,
uint32_t * num_drivers ,
const char * * * drivers )
{
uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED ;
struct rpc_pipe_client * winreg_pipe = NULL ;
struct policy_handle hive_hnd , key_hnd ;
TALLOC_CTX * tmp_ctx ;
WERROR result ;
ZERO_STRUCT ( hive_hnd ) ;
ZERO_STRUCT ( key_hnd ) ;
tmp_ctx = talloc_new ( mem_ctx ) ;
if ( tmp_ctx = = NULL ) {
return WERR_NOMEM ;
}
/* use NULL for the driver name so we open the key that is
* parent of all drivers for this architecture and version */
result = winreg_printer_opendriver ( tmp_ctx ,
server_info ,
NULL ,
architecture ,
version ,
access_mask , false ,
& winreg_pipe ,
& hive_hnd ,
& key_hnd ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
DEBUG ( 5 , ( " winreg_get_driver_list: "
" Could not open key (%s,%u): %s \n " ,
architecture , version , win_errstr ( result ) ) ) ;
goto done ;
}
result = winreg_printer_enumkeys ( tmp_ctx ,
winreg_pipe ,
& key_hnd ,
num_drivers ,
drivers ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
DEBUG ( 0 , ( " winreg_get_driver_list: "
" Could not enumerate drivers for (%s,%u): %s \n " ,
architecture , version , win_errstr ( result ) ) ) ;
goto done ;
}
result = WERR_OK ;
done :
if ( winreg_pipe ! = NULL ) {
if ( is_valid_policy_hnd ( & key_hnd ) ) {
rpccli_winreg_CloseKey ( winreg_pipe , tmp_ctx , & key_hnd , NULL ) ;
}
if ( is_valid_policy_hnd ( & hive_hnd ) ) {
rpccli_winreg_CloseKey ( winreg_pipe , tmp_ctx , & hive_hnd , NULL ) ;
}
}
TALLOC_FREE ( tmp_ctx ) ;
return result ;
}