Changeset 740 for vendor/current/source3/printing/nt_printing.c
- Timestamp:
- Nov 14, 2012, 12:59:34 PM (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
TabularUnified vendor/current/source3/printing/nt_printing.c ¶
r597 r740 21 21 22 22 #include "includes.h" 23 24 static TDB_CONTEXT *tdb_forms; /* used for forms files */ 25 static TDB_CONTEXT *tdb_drivers; /* used for driver files */ 26 static TDB_CONTEXT *tdb_printers; /* used for printers files */ 27 28 #define FORMS_PREFIX "FORMS/" 29 #define DRIVERS_PREFIX "DRIVERS/" 30 #define DRIVER_INIT_PREFIX "DRIVER_INIT/" 31 #define PRINTERS_PREFIX "PRINTERS/" 32 #define SECDESC_PREFIX "SECDESC/" 33 #define GLOBAL_C_SETPRINTER "GLOBALS/c_setprinter" 34 35 #define NTDRIVERS_DATABASE_VERSION_1 1 36 #define NTDRIVERS_DATABASE_VERSION_2 2 37 #define NTDRIVERS_DATABASE_VERSION_3 3 /* little endian version of v2 */ 38 #define NTDRIVERS_DATABASE_VERSION_4 4 /* fix generic bits in security descriptors */ 39 #define NTDRIVERS_DATABASE_VERSION_5 5 /* normalize keys in ntprinters.tdb */ 23 #include "printing/nt_printing_tdb.h" 24 #include "../librpc/gen_ndr/ndr_spoolss.h" 25 #include "rpc_server/spoolss/srv_spoolss_util.h" 26 #include "nt_printing.h" 27 #include "secrets.h" 28 #include "../librpc/gen_ndr/netlogon.h" 29 #include "../libcli/security/security.h" 30 #include "passdb/machine_sid.h" 31 #include "smbd/smbd.h" 32 #include "auth.h" 33 #include "messages.h" 34 #include "rpc_server/spoolss/srv_spoolss_nt.h" 35 #include "rpc_client/cli_winreg_spoolss.h" 40 36 41 37 /* Map generic permissions to printer object specific permissions */ … … 48 44 }; 49 45 50 const struct standard_mapping printer_std_mapping = {51 PRINTER_READ,52 PRINTER_WRITE,53 PRINTER_EXECUTE,54 PRINTER_ALL_ACCESS55 };56 57 46 /* Map generic permissions to print server object specific permissions */ 58 47 … … 64 53 }; 65 54 66 const struct generic_mapping printserver_std_mapping = {67 SERVER_READ,68 SERVER_WRITE,69 SERVER_EXECUTE,70 SERVER_ALL_ACCESS71 };72 73 55 /* Map generic permissions to job object specific permissions */ 74 56 … … 78 60 JOB_EXECUTE, 79 61 JOB_ALL_ACCESS 80 };81 82 /* We need one default form to support our default printer. Msoft adds the83 forms it wants and in the ORDER it wants them (note: DEVMODE papersize is an84 array index). Letter is always first, so (for the current code) additions85 always put things in the correct order. */86 static const nt_forms_struct default_forms[] = {87 {"Letter",0x1,0x34b5c,0x44368,0x0,0x0,0x34b5c,0x44368},88 {"Letter Small",0x1,0x34b5c,0x44368,0x0,0x0,0x34b5c,0x44368},89 {"Tabloid",0x1,0x44368,0x696b8,0x0,0x0,0x44368,0x696b8},90 {"Ledger",0x1,0x696b8,0x44368,0x0,0x0,0x696b8,0x44368},91 {"Legal",0x1,0x34b5c,0x56d10,0x0,0x0,0x34b5c,0x56d10},92 {"Statement",0x1,0x221b4,0x34b5c,0x0,0x0,0x221b4,0x34b5c},93 {"Executive",0x1,0x2cf56,0x411cc,0x0,0x0,0x2cf56,0x411cc},94 {"A3",0x1,0x48828,0x668a0,0x0,0x0,0x48828,0x668a0},95 {"A4",0x1,0x33450,0x48828,0x0,0x0,0x33450,0x48828},96 {"A4 Small",0x1,0x33450,0x48828,0x0,0x0,0x33450,0x48828},97 {"A5",0x1,0x24220,0x33450,0x0,0x0,0x24220,0x33450},98 {"B4 (JIS)",0x1,0x3ebe8,0x58de0,0x0,0x0,0x3ebe8,0x58de0},99 {"B5 (JIS)",0x1,0x2c6f0,0x3ebe8,0x0,0x0,0x2c6f0,0x3ebe8},100 {"Folio",0x1,0x34b5c,0x509d8,0x0,0x0,0x34b5c,0x509d8},101 {"Quarto",0x1,0x347d8,0x43238,0x0,0x0,0x347d8,0x43238},102 {"10x14",0x1,0x3e030,0x56d10,0x0,0x0,0x3e030,0x56d10},103 {"11x17",0x1,0x44368,0x696b8,0x0,0x0,0x44368,0x696b8},104 {"Note",0x1,0x34b5c,0x44368,0x0,0x0,0x34b5c,0x44368},105 {"Envelope #9",0x1,0x18079,0x37091,0x0,0x0,0x18079,0x37091},106 {"Envelope #10",0x1,0x19947,0x3ae94,0x0,0x0,0x19947,0x3ae94},107 {"Envelope #11",0x1,0x1be7c,0x40565,0x0,0x0,0x1be7c,0x40565},108 {"Envelope #12",0x1,0x1d74a,0x44368,0x0,0x0,0x1d74a,0x44368},109 {"Envelope #14",0x1,0x1f018,0x47504,0x0,0x0,0x1f018,0x47504},110 {"C size sheet",0x1,0x696b8,0x886d0,0x0,0x0,0x696b8,0x886d0},111 {"D size sheet",0x1,0x886d0,0xd2d70,0x0,0x0,0x886d0,0xd2d70},112 {"E size sheet",0x1,0xd2d70,0x110da0,0x0,0x0,0xd2d70,0x110da0},113 {"Envelope DL",0x1,0x1adb0,0x35b60,0x0,0x0,0x1adb0,0x35b60},114 {"Envelope C5",0x1,0x278d0,0x37e88,0x0,0x0,0x278d0,0x37e88},115 {"Envelope C3",0x1,0x4f1a0,0x6fd10,0x0,0x0,0x4f1a0,0x6fd10},116 {"Envelope C4",0x1,0x37e88,0x4f1a0,0x0,0x0,0x37e88,0x4f1a0},117 {"Envelope C6",0x1,0x1bd50,0x278d0,0x0,0x0,0x1bd50,0x278d0},118 {"Envelope C65",0x1,0x1bd50,0x37e88,0x0,0x0,0x1bd50,0x37e88},119 {"Envelope B4",0x1,0x3d090,0x562e8,0x0,0x0,0x3d090,0x562e8},120 {"Envelope B5",0x1,0x2af80,0x3d090,0x0,0x0,0x2af80,0x3d090},121 {"Envelope B6",0x1,0x2af80,0x1e848,0x0,0x0,0x2af80,0x1e848},122 {"Envelope",0x1,0x1adb0,0x38270,0x0,0x0,0x1adb0,0x38270},123 {"Envelope Monarch",0x1,0x18079,0x2e824,0x0,0x0,0x18079,0x2e824},124 {"6 3/4 Envelope",0x1,0x167ab,0x284ec,0x0,0x0,0x167ab,0x284ec},125 {"US Std Fanfold",0x1,0x5c3e1,0x44368,0x0,0x0,0x5c3e1,0x44368},126 {"German Std Fanfold",0x1,0x34b5c,0x4a6a0,0x0,0x0,0x34b5c,0x4a6a0},127 {"German Legal Fanfold",0x1,0x34b5c,0x509d8,0x0,0x0,0x34b5c,0x509d8},128 {"B4 (ISO)",0x1,0x3d090,0x562e8,0x0,0x0,0x3d090,0x562e8},129 {"Japanese Postcard",0x1,0x186a0,0x24220,0x0,0x0,0x186a0,0x24220},130 {"9x11",0x1,0x37cf8,0x44368,0x0,0x0,0x37cf8,0x44368},131 {"10x11",0x1,0x3e030,0x44368,0x0,0x0,0x3e030,0x44368},132 {"15x11",0x1,0x5d048,0x44368,0x0,0x0,0x5d048,0x44368},133 {"Envelope Invite",0x1,0x35b60,0x35b60,0x0,0x0,0x35b60,0x35b60},134 {"Reserved48",0x1,0x1,0x1,0x0,0x0,0x1,0x1},135 {"Reserved49",0x1,0x1,0x1,0x0,0x0,0x1,0x1},136 {"Letter Extra",0x1,0x3ae94,0x4a6a0,0x0,0x0,0x3ae94,0x4a6a0},137 {"Legal Extra",0x1,0x3ae94,0x5d048,0x0,0x0,0x3ae94,0x5d048},138 {"Tabloid Extra",0x1,0x4a6a0,0x6f9f0,0x0,0x0,0x4a6a0,0x6f9f0},139 {"A4 Extra",0x1,0x397c2,0x4eb16,0x0,0x0,0x397c2,0x4eb16},140 {"Letter Transverse",0x1,0x34b5c,0x44368,0x0,0x0,0x34b5c,0x44368},141 {"A4 Transverse",0x1,0x33450,0x48828,0x0,0x0,0x33450,0x48828},142 {"Letter Extra Transverse",0x1,0x3ae94,0x4a6a0,0x0,0x0,0x3ae94,0x4a6a0},143 {"Super A",0x1,0x376b8,0x56ea0,0x0,0x0,0x376b8,0x56ea0},144 {"Super B",0x1,0x4a768,0x76e58,0x0,0x0,0x4a768,0x76e58},145 {"Letter Plus",0x1,0x34b5c,0x4eb16,0x0,0x0,0x34b5c,0x4eb16},146 {"A4 Plus",0x1,0x33450,0x50910,0x0,0x0,0x33450,0x50910},147 {"A5 Transverse",0x1,0x24220,0x33450,0x0,0x0,0x24220,0x33450},148 {"B5 (JIS) Transverse",0x1,0x2c6f0,0x3ebe8,0x0,0x0,0x2c6f0,0x3ebe8},149 {"A3 Extra",0x1,0x4e9d0,0x6ca48,0x0,0x0,0x4e9d0,0x6ca48},150 {"A5 Extra",0x1,0x2a7b0,0x395f8,0x0,0x0,0x2a7b0,0x395f8},151 {"B5 (ISO) Extra",0x1,0x31128,0x43620,0x0,0x0,0x31128,0x43620},152 {"A2",0x1,0x668a0,0x91050,0x0,0x0,0x668a0,0x91050},153 {"A3 Transverse",0x1,0x48828,0x668a0,0x0,0x0,0x48828,0x668a0},154 {"A3 Extra Transverse",0x1,0x4e9d0,0x6ca48,0x0,0x0,0x4e9d0,0x6ca48},155 {"Japanese Double Postcard",0x1,0x30d40,0x24220,0x0,0x0,0x30d40,0x24220},156 {"A6",0x1,0x19a28,0x24220,0x0,0x0,0x19a28,0x24220},157 {"Japanese Envelope Kaku #2",0x1,0x3a980,0x510e0,0x0,0x0,0x3a980,0x510e0},158 {"Japanese Envelope Kaku #3",0x1,0x34bc0,0x43a08,0x0,0x0,0x34bc0,0x43a08},159 {"Japanese Envelope Chou #3",0x1,0x1d4c0,0x395f8,0x0,0x0,0x1d4c0,0x395f8},160 {"Japanese Envelope Chou #4",0x1,0x15f90,0x320c8,0x0,0x0,0x15f90,0x320c8},161 {"Letter Rotated",0x1,0x44368,0x34b5c,0x0,0x0,0x44368,0x34b5c},162 {"A3 Rotated",0x1,0x668a0,0x48828,0x0,0x0,0x668a0,0x48828},163 {"A4 Rotated",0x1,0x48828,0x33450,0x0,0x0,0x48828,0x33450},164 {"A5 Rotated",0x1,0x33450,0x24220,0x0,0x0,0x33450,0x24220},165 {"B4 (JIS) Rotated",0x1,0x58de0,0x3ebe8,0x0,0x0,0x58de0,0x3ebe8},166 {"B5 (JIS) Rotated",0x1,0x3ebe8,0x2c6f0,0x0,0x0,0x3ebe8,0x2c6f0},167 {"Japanese Postcard Rotated",0x1,0x24220,0x186a0,0x0,0x0,0x24220,0x186a0},168 {"Double Japan Postcard Rotated",0x1,0x24220,0x30d40,0x0,0x0,0x24220,0x30d40},169 {"A6 Rotated",0x1,0x24220,0x19a28,0x0,0x0,0x24220,0x19a28},170 {"Japan Envelope Kaku #2 Rotated",0x1,0x510e0,0x3a980,0x0,0x0,0x510e0,0x3a980},171 {"Japan Envelope Kaku #3 Rotated",0x1,0x43a08,0x34bc0,0x0,0x0,0x43a08, 0x34bc0},172 {"Japan Envelope Chou #3 Rotated",0x1,0x395f8,0x1d4c0,0x0,0x0,0x395f8,0x1d4c0},173 {"Japan Envelope Chou #4 Rotated",0x1,0x320c8,0x15f90,0x0,0x0,0x320c8,0x15f90},174 {"B6 (JIS)",0x1,0x1f400,0x2c6f0,0x0,0x0,0x1f400,0x2c6f0},175 {"B6 (JIS) Rotated",0x1,0x2c6f0,0x1f400,0x0,0x0,0x2c6f0,0x1f400},176 {"12x11",0x1,0x4a724,0x443e1,0x0,0x0,0x4a724,0x443e1},177 {"Japan Envelope You #4",0x1,0x19a28,0x395f8,0x0,0x0,0x19a28,0x395f8},178 {"Japan Envelope You #4 Rotated",0x1,0x395f8,0x19a28,0x0,0x0,0x395f8,0x19a28},179 {"PRC 16K",0x1,0x2de60,0x3f7a0,0x0,0x0,0x2de60,0x3f7a0},180 {"PRC 32K",0x1,0x1fbd0,0x2cec0,0x0,0x0,0x1fbd0,0x2cec0},181 {"PRC 32K(Big)",0x1,0x222e0,0x318f8,0x0,0x0,0x222e0,0x318f8},182 {"PRC Envelope #1",0x1,0x18e70,0x28488,0x0,0x0,0x18e70,0x28488},183 {"PRC Envelope #2",0x1,0x18e70,0x2af80,0x0,0x0,0x18e70,0x2af80},184 {"PRC Envelope #3",0x1,0x1e848,0x2af80,0x0,0x0,0x1e848,0x2af80},185 {"PRC Envelope #4",0x1,0x1adb0,0x32c80,0x0,0x0,0x1adb0,0x32c80},186 {"PRC Envelope #5",0x1,0x1adb0,0x35b60,0x0,0x0,0x1adb0,0x35b60},187 {"PRC Envelope #6",0x1,0x1d4c0,0x38270,0x0,0x0,0x1d4c0,0x38270},188 {"PRC Envelope #7",0x1,0x27100,0x38270,0x0,0x0,0x27100,0x38270},189 {"PRC Envelope #8",0x1,0x1d4c0,0x4b708,0x0,0x0,0x1d4c0,0x4b708},190 {"PRC Envelope #9",0x1,0x37e88,0x4f1a0,0x0,0x0,0x37e88,0x4f1a0},191 {"PRC Envelope #10",0x1,0x4f1a0,0x6fd10,0x0,0x0,0x4f1a0,0x6fd10},192 {"PRC 16K Rotated",0x1,0x3f7a0,0x2de60,0x0,0x0,0x3f7a0,0x2de60},193 {"PRC 32K Rotated",0x1,0x2cec0,0x1fbd0,0x0,0x0,0x2cec0,0x1fbd0},194 {"PRC 32K(Big) Rotated",0x1,0x318f8,0x222e0,0x0,0x0,0x318f8,0x222e0},195 {"PRC Envelope #1 Rotated",0x1,0x28488,0x18e70,0x0,0x0,0x28488,0x18e70},196 {"PRC Envelope #2 Rotated",0x1,0x2af80,0x18e70,0x0,0x0,0x2af80,0x18e70},197 {"PRC Envelope #3 Rotated",0x1,0x2af80,0x1e848,0x0,0x0,0x2af80,0x1e848},198 {"PRC Envelope #4 Rotated",0x1,0x32c80,0x1adb0,0x0,0x0,0x32c80,0x1adb0},199 {"PRC Envelope #5 Rotated",0x1,0x35b60,0x1adb0,0x0,0x0,0x35b60,0x1adb0},200 {"PRC Envelope #6 Rotated",0x1,0x38270,0x1d4c0,0x0,0x0,0x38270,0x1d4c0},201 {"PRC Envelope #7 Rotated",0x1,0x38270,0x27100,0x0,0x0,0x38270,0x27100},202 {"PRC Envelope #8 Rotated",0x1,0x4b708,0x1d4c0,0x0,0x0,0x4b708,0x1d4c0},203 {"PRC Envelope #9 Rotated",0x1,0x4f1a0,0x37e88,0x0,0x0,0x4f1a0,0x37e88},204 {"PRC Envelope #10 Rotated",0x1,0x6fd10,0x4f1a0,0x0,0x0,0x6fd10,0x4f1a0}205 62 }; 206 63 … … 217 74 }; 218 75 219 220 /****************************************************************************221 generate a new TDB_DATA key for storing a printer222 ****************************************************************************/223 224 static TDB_DATA make_printer_tdbkey(TALLOC_CTX *ctx, const char *sharename )225 {226 fstring share;227 char *keystr = NULL;228 TDB_DATA key;229 230 fstrcpy(share, sharename);231 strlower_m(share);232 233 keystr = talloc_asprintf(ctx, "%s%s", PRINTERS_PREFIX, share);234 key = string_term_tdb_data(keystr ? keystr : "");235 236 return key;237 }238 239 /****************************************************************************240 generate a new TDB_DATA key for storing a printer security descriptor241 ****************************************************************************/242 243 static TDB_DATA make_printers_secdesc_tdbkey(TALLOC_CTX *ctx,244 const char* sharename )245 {246 fstring share;247 char *keystr = NULL;248 TDB_DATA key;249 250 fstrcpy(share, sharename );251 strlower_m(share);252 253 keystr = talloc_asprintf(ctx, "%s%s", SECDESC_PREFIX, share);254 key = string_term_tdb_data(keystr ? keystr : "");255 256 return key;257 }258 259 /****************************************************************************260 ****************************************************************************/261 262 static bool upgrade_to_version_3(void)263 {264 TDB_DATA kbuf, newkey, dbuf;265 266 DEBUG(0,("upgrade_to_version_3: upgrading print tdb's to version 3\n"));267 268 for (kbuf = tdb_firstkey(tdb_drivers); kbuf.dptr;269 newkey = tdb_nextkey(tdb_drivers, kbuf), free(kbuf.dptr), kbuf=newkey) {270 271 dbuf = tdb_fetch(tdb_drivers, kbuf);272 273 if (strncmp((const char *)kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) == 0) {274 DEBUG(0,("upgrade_to_version_3:moving form\n"));275 if (tdb_store(tdb_forms, kbuf, dbuf, TDB_REPLACE) != 0) {276 SAFE_FREE(dbuf.dptr);277 DEBUG(0,("upgrade_to_version_3: failed to move form. Error (%s).\n", tdb_errorstr(tdb_forms)));278 return False;279 }280 if (tdb_delete(tdb_drivers, kbuf) != 0) {281 SAFE_FREE(dbuf.dptr);282 DEBUG(0,("upgrade_to_version_3: failed to delete form. Error (%s)\n", tdb_errorstr(tdb_drivers)));283 return False;284 }285 }286 287 if (strncmp((const char *)kbuf.dptr, PRINTERS_PREFIX, strlen(PRINTERS_PREFIX)) == 0) {288 DEBUG(0,("upgrade_to_version_3:moving printer\n"));289 if (tdb_store(tdb_printers, kbuf, dbuf, TDB_REPLACE) != 0) {290 SAFE_FREE(dbuf.dptr);291 DEBUG(0,("upgrade_to_version_3: failed to move printer. Error (%s)\n", tdb_errorstr(tdb_printers)));292 return False;293 }294 if (tdb_delete(tdb_drivers, kbuf) != 0) {295 SAFE_FREE(dbuf.dptr);296 DEBUG(0,("upgrade_to_version_3: failed to delete printer. Error (%s)\n", tdb_errorstr(tdb_drivers)));297 return False;298 }299 }300 301 if (strncmp((const char *)kbuf.dptr, SECDESC_PREFIX, strlen(SECDESC_PREFIX)) == 0) {302 DEBUG(0,("upgrade_to_version_3:moving secdesc\n"));303 if (tdb_store(tdb_printers, kbuf, dbuf, TDB_REPLACE) != 0) {304 SAFE_FREE(dbuf.dptr);305 DEBUG(0,("upgrade_to_version_3: failed to move secdesc. Error (%s)\n", tdb_errorstr(tdb_printers)));306 return False;307 }308 if (tdb_delete(tdb_drivers, kbuf) != 0) {309 SAFE_FREE(dbuf.dptr);310 DEBUG(0,("upgrade_to_version_3: failed to delete secdesc. Error (%s)\n", tdb_errorstr(tdb_drivers)));311 return False;312 }313 }314 315 SAFE_FREE(dbuf.dptr);316 }317 318 return True;319 }320 321 /*******************************************************************322 Fix an issue with security descriptors. Printer sec_desc must323 use more than the generic bits that were previously used324 in <= 3.0.14a. They must also have a owner and group SID assigned.325 Otherwise, any printers than have been migrated to a Windows326 host using printmig.exe will not be accessible.327 *******************************************************************/328 329 static int sec_desc_upg_fn( TDB_CONTEXT *the_tdb, TDB_DATA key,330 TDB_DATA data, void *state )331 {332 NTSTATUS status;333 SEC_DESC_BUF *sd_orig = NULL;334 SEC_DESC_BUF *sd_new, *sd_store;335 SEC_DESC *sec, *new_sec;336 TALLOC_CTX *ctx = state;337 int result, i;338 uint32 sd_size;339 size_t size_new_sec;340 341 if (!data.dptr || data.dsize == 0) {342 return 0;343 }344 345 if ( strncmp((const char *) key.dptr, SECDESC_PREFIX, strlen(SECDESC_PREFIX) ) != 0 ) {346 return 0;347 }348 349 /* upgrade the security descriptor */350 351 status = unmarshall_sec_desc_buf(ctx, data.dptr, data.dsize, &sd_orig);352 if (!NT_STATUS_IS_OK(status)) {353 /* delete bad entries */354 DEBUG(0,("sec_desc_upg_fn: Failed to parse original sec_desc for %si. Deleting....\n",355 (const char *)key.dptr ));356 tdb_delete( tdb_printers, key );357 return 0;358 }359 360 if (!sd_orig) {361 return 0;362 }363 sec = sd_orig->sd;364 365 /* is this even valid? */366 367 if ( !sec->dacl ) {368 return 0;369 }370 371 /* update access masks */372 373 for ( i=0; i<sec->dacl->num_aces; i++ ) {374 switch ( sec->dacl->aces[i].access_mask ) {375 case (GENERIC_READ_ACCESS | GENERIC_WRITE_ACCESS | GENERIC_EXECUTE_ACCESS):376 sec->dacl->aces[i].access_mask = PRINTER_ACE_PRINT;377 break;378 379 case GENERIC_ALL_ACCESS:380 sec->dacl->aces[i].access_mask = PRINTER_ACE_FULL_CONTROL;381 break;382 383 case READ_CONTROL_ACCESS:384 sec->dacl->aces[i].access_mask = PRINTER_ACE_MANAGE_DOCUMENTS;385 386 default: /* no change */387 break;388 }389 }390 391 /* create a new SEC_DESC with the appropriate owner and group SIDs */392 393 new_sec = make_sec_desc( ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE,394 &global_sid_Builtin_Administrators,395 &global_sid_Builtin_Administrators,396 NULL, NULL, &size_new_sec );397 if (!new_sec) {398 return 0;399 }400 sd_new = make_sec_desc_buf( ctx, size_new_sec, new_sec );401 if (!sd_new) {402 return 0;403 }404 405 if ( !(sd_store = sec_desc_merge( ctx, sd_new, sd_orig )) ) {406 DEBUG(0,("sec_desc_upg_fn: Failed to update sec_desc for %s\n", key.dptr ));407 return 0;408 }409 410 /* store it back */411 412 sd_size = ndr_size_security_descriptor(sd_store->sd, NULL, 0)413 + sizeof(SEC_DESC_BUF);414 415 status = marshall_sec_desc_buf(ctx, sd_store, &data.dptr, &data.dsize);416 if (!NT_STATUS_IS_OK(status)) {417 DEBUG(0,("sec_desc_upg_fn: Failed to parse new sec_desc for %s\n", key.dptr ));418 return 0;419 }420 421 result = tdb_store( tdb_printers, key, data, TDB_REPLACE );422 423 /* 0 to continue and non-zero to stop traversal */424 425 return (result == -1);426 }427 428 /*******************************************************************429 *******************************************************************/430 431 static bool upgrade_to_version_4(void)432 {433 TALLOC_CTX *ctx;434 int result;435 436 DEBUG(0,("upgrade_to_version_4: upgrading printer security descriptors\n"));437 438 if ( !(ctx = talloc_init( "upgrade_to_version_4" )) )439 return False;440 441 result = tdb_traverse( tdb_printers, sec_desc_upg_fn, ctx );442 443 talloc_destroy( ctx );444 445 return ( result != -1 );446 }447 448 /*******************************************************************449 Fix an issue with security descriptors. Printer sec_desc must450 use more than the generic bits that were previously used451 in <= 3.0.14a. They must also have a owner and group SID assigned.452 Otherwise, any printers than have been migrated to a Windows453 host using printmig.exe will not be accessible.454 *******************************************************************/455 456 static int normalize_printers_fn( TDB_CONTEXT *the_tdb, TDB_DATA key,457 TDB_DATA data, void *state )458 {459 TALLOC_CTX *ctx = talloc_tos();460 TDB_DATA new_key;461 462 if (!data.dptr || data.dsize == 0)463 return 0;464 465 /* upgrade printer records and security descriptors */466 467 if ( strncmp((const char *) key.dptr, PRINTERS_PREFIX, strlen(PRINTERS_PREFIX) ) == 0 ) {468 new_key = make_printer_tdbkey(ctx, (const char *)key.dptr+strlen(PRINTERS_PREFIX) );469 }470 else if ( strncmp((const char *) key.dptr, SECDESC_PREFIX, strlen(SECDESC_PREFIX) ) == 0 ) {471 new_key = make_printers_secdesc_tdbkey(ctx, (const char *)key.dptr+strlen(SECDESC_PREFIX) );472 }473 else {474 /* ignore this record */475 return 0;476 }477 478 /* delete the original record and store under the normalized key */479 480 if ( tdb_delete( the_tdb, key ) != 0 ) {481 DEBUG(0,("normalize_printers_fn: tdb_delete for [%s] failed!\n",482 key.dptr));483 return 1;484 }485 486 if ( tdb_store( the_tdb, new_key, data, TDB_REPLACE) != 0 ) {487 DEBUG(0,("normalize_printers_fn: failed to store new record for [%s]!\n",488 key.dptr));489 return 1;490 }491 492 return 0;493 }494 495 /*******************************************************************496 *******************************************************************/497 498 static bool upgrade_to_version_5(void)499 {500 TALLOC_CTX *ctx;501 int result;502 503 DEBUG(0,("upgrade_to_version_5: normalizing printer keys\n"));504 505 if ( !(ctx = talloc_init( "upgrade_to_version_5" )) )506 return False;507 508 result = tdb_traverse( tdb_printers, normalize_printers_fn, NULL );509 510 talloc_destroy( ctx );511 512 return ( result != -1 );513 }514 515 76 /**************************************************************************** 516 77 Open the NT printing tdbs. Done once before fork(). … … 519 80 bool nt_printing_init(struct messaging_context *msg_ctx) 520 81 { 521 const char *vstring = "INFO/version";522 82 WERROR win_rc; 523 int32 vers_id; 524 525 if ( tdb_drivers && tdb_printers && tdb_forms ) 526 return True; 527 528 if (tdb_drivers) 529 tdb_close(tdb_drivers); 530 tdb_drivers = tdb_open_log(state_path("ntdrivers.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600); 531 if (!tdb_drivers) { 532 DEBUG(0,("nt_printing_init: Failed to open nt drivers database %s (%s)\n", 533 state_path("ntdrivers.tdb"), strerror(errno) )); 534 return False; 535 } 536 537 if (tdb_printers) 538 tdb_close(tdb_printers); 539 tdb_printers = tdb_open_log(state_path("ntprinters.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600); 540 if (!tdb_printers) { 541 DEBUG(0,("nt_printing_init: Failed to open nt printers database %s (%s)\n", 542 state_path("ntprinters.tdb"), strerror(errno) )); 543 return False; 544 } 545 546 if (tdb_forms) 547 tdb_close(tdb_forms); 548 tdb_forms = tdb_open_log(state_path("ntforms.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600); 549 if (!tdb_forms) { 550 DEBUG(0,("nt_printing_init: Failed to open nt forms database %s (%s)\n", 551 state_path("ntforms.tdb"), strerror(errno) )); 552 return False; 553 } 554 555 /* handle a Samba upgrade */ 556 557 vers_id = tdb_fetch_int32(tdb_drivers, vstring); 558 if (vers_id == -1) { 559 DEBUG(10, ("Fresh database\n")); 560 tdb_store_int32( tdb_drivers, vstring, NTDRIVERS_DATABASE_VERSION_5 ); 561 vers_id = NTDRIVERS_DATABASE_VERSION_5; 562 } 563 564 if ( vers_id != NTDRIVERS_DATABASE_VERSION_5 ) { 565 566 if ((vers_id == NTDRIVERS_DATABASE_VERSION_1) || (IREV(vers_id) == NTDRIVERS_DATABASE_VERSION_1)) { 567 if (!upgrade_to_version_3()) 568 return False; 569 tdb_store_int32(tdb_drivers, vstring, NTDRIVERS_DATABASE_VERSION_3); 570 vers_id = NTDRIVERS_DATABASE_VERSION_3; 571 } 572 573 if ((vers_id == NTDRIVERS_DATABASE_VERSION_2) || (IREV(vers_id) == NTDRIVERS_DATABASE_VERSION_2)) { 574 /* Written on a bigendian machine with old fetch_int code. Save as le. */ 575 /* The only upgrade between V2 and V3 is to save the version in little-endian. */ 576 tdb_store_int32(tdb_drivers, vstring, NTDRIVERS_DATABASE_VERSION_3); 577 vers_id = NTDRIVERS_DATABASE_VERSION_3; 578 } 579 580 if (vers_id == NTDRIVERS_DATABASE_VERSION_3 ) { 581 if ( !upgrade_to_version_4() ) 582 return False; 583 tdb_store_int32(tdb_drivers, vstring, NTDRIVERS_DATABASE_VERSION_4); 584 vers_id = NTDRIVERS_DATABASE_VERSION_4; 585 } 586 587 if (vers_id == NTDRIVERS_DATABASE_VERSION_4 ) { 588 if ( !upgrade_to_version_5() ) 589 return False; 590 tdb_store_int32(tdb_drivers, vstring, NTDRIVERS_DATABASE_VERSION_5); 591 vers_id = NTDRIVERS_DATABASE_VERSION_5; 592 } 593 594 595 if ( vers_id != NTDRIVERS_DATABASE_VERSION_5 ) { 596 DEBUG(0,("nt_printing_init: Unknown printer database version [%d]\n", vers_id)); 597 return False; 598 } 599 } 600 601 update_c_setprinter(True); 83 84 if (!nt_printing_tdb_upgrade()) { 85 return false; 86 } 602 87 603 88 /* … … 605 90 * drivers are installed 606 91 */ 607 608 92 messaging_register(msg_ctx, NULL, MSG_PRINTER_DRVUPGRADE, 609 93 do_drv_upgrade_printer); 610 94 611 /*612 * register callback to handle updating printer data613 * when a driver is initialized614 */615 616 messaging_register(msg_ctx, NULL, MSG_PRINTERDATA_INIT_RESET,617 reset_all_printerdata);618 619 95 /* of course, none of the message callbacks matter if you don't 620 96 tell messages.c that you interested in receiving PRINT_GENERAL 621 msgs. This is done in claim_connection() */ 622 97 msgs. This is done in serverid_register() */ 623 98 624 99 if ( lp_security() == SEC_ADS ) { 625 win_rc = check_published_printers( );100 win_rc = check_published_printers(msg_ctx); 626 101 if (!W_ERROR_IS_OK(win_rc)) 627 102 DEBUG(0, ("nt_printing_init: error checking published printers: %s\n", win_errstr(win_rc))); 628 103 } 629 104 630 return True;105 return true; 631 106 } 632 107 … … 661 136 } 662 137 663 /*******************************************************************664 tdb traversal function for counting printers.665 ********************************************************************/666 667 static int traverse_counting_printers(TDB_CONTEXT *t, TDB_DATA key,668 TDB_DATA data, void *context)669 {670 int *printer_count = (int*)context;671 672 if (memcmp(PRINTERS_PREFIX, key.dptr, sizeof(PRINTERS_PREFIX)-1) == 0) {673 (*printer_count)++;674 DEBUG(10,("traverse_counting_printers: printer = [%s] printer_count = %d\n", key.dptr, *printer_count));675 }676 677 return 0;678 }679 680 /*******************************************************************681 Update the spooler global c_setprinter. This variable is initialized682 when the parent smbd starts with the number of existing printers. It683 is monotonically increased by the current number of printers *after*684 each add or delete printer RPC. Only Microsoft knows why... JRR020119685 ********************************************************************/686 687 uint32 update_c_setprinter(bool initialize)688 {689 int32 c_setprinter;690 int32 printer_count = 0;691 692 tdb_lock_bystring(tdb_printers, GLOBAL_C_SETPRINTER);693 694 /* Traverse the tdb, counting the printers */695 tdb_traverse(tdb_printers, traverse_counting_printers, (void *)&printer_count);696 697 /* If initializing, set c_setprinter to current printers count698 * otherwise, bump it by the current printer count699 */700 if (!initialize)701 c_setprinter = tdb_fetch_int32(tdb_printers, GLOBAL_C_SETPRINTER) + printer_count;702 else703 c_setprinter = printer_count;704 705 DEBUG(10,("update_c_setprinter: c_setprinter = %u\n", (unsigned int)c_setprinter));706 tdb_store_int32(tdb_printers, GLOBAL_C_SETPRINTER, c_setprinter);707 708 tdb_unlock_bystring(tdb_printers, GLOBAL_C_SETPRINTER);709 710 return (uint32)c_setprinter;711 }712 713 /*******************************************************************714 Get the spooler global c_setprinter, accounting for initialization.715 ********************************************************************/716 717 uint32 get_c_setprinter(void)718 {719 int32 c_setprinter = tdb_fetch_int32(tdb_printers, GLOBAL_C_SETPRINTER);720 721 if (c_setprinter == (int32)-1)722 c_setprinter = update_c_setprinter(True);723 724 DEBUG(10,("get_c_setprinter: c_setprinter = %d\n", c_setprinter));725 726 return (uint32)c_setprinter;727 }728 729 /****************************************************************************730 Get builtin form struct list.731 ****************************************************************************/732 733 int get_builtin_ntforms(nt_forms_struct **list)734 {735 *list = (nt_forms_struct *)memdup(&default_forms[0], sizeof(default_forms));736 if (!*list) {737 return 0;738 }739 return ARRAY_SIZE(default_forms);740 }741 742 /****************************************************************************743 get a builtin form struct744 ****************************************************************************/745 746 bool get_a_builtin_ntform_by_string(const char *form_name, nt_forms_struct *form)747 {748 int i;749 DEBUGADD(6,("Looking for builtin form %s \n", form_name));750 for (i=0; i<ARRAY_SIZE(default_forms); i++) {751 if (strequal(form_name,default_forms[i].name)) {752 DEBUGADD(6,("Found builtin form %s \n", form_name));753 memcpy(form,&default_forms[i],sizeof(*form));754 return true;755 }756 }757 758 return false;759 }760 761 /****************************************************************************762 get a form struct list.763 ****************************************************************************/764 765 int get_ntforms(nt_forms_struct **list)766 {767 TDB_DATA kbuf, newkey, dbuf;768 nt_forms_struct form;769 int ret;770 int i;771 int n = 0;772 773 *list = NULL;774 775 for (kbuf = tdb_firstkey(tdb_forms);776 kbuf.dptr;777 newkey = tdb_nextkey(tdb_forms, kbuf), free(kbuf.dptr), kbuf=newkey)778 {779 if (strncmp((const char *)kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) != 0)780 continue;781 782 dbuf = tdb_fetch(tdb_forms, kbuf);783 if (!dbuf.dptr)784 continue;785 786 fstrcpy(form.name, (const char *)kbuf.dptr+strlen(FORMS_PREFIX));787 ret = tdb_unpack(dbuf.dptr, dbuf.dsize, "dddddddd",788 &i, &form.flag, &form.width, &form.length, &form.left,789 &form.top, &form.right, &form.bottom);790 SAFE_FREE(dbuf.dptr);791 if (ret != dbuf.dsize)792 continue;793 794 *list = SMB_REALLOC_ARRAY(*list, nt_forms_struct, n+1);795 if (!*list) {796 DEBUG(0,("get_ntforms: Realloc fail.\n"));797 return 0;798 }799 (*list)[n] = form;800 n++;801 }802 803 804 return n;805 }806 807 /****************************************************************************808 write a form struct list809 ****************************************************************************/810 811 int write_ntforms(nt_forms_struct **list, int number)812 {813 TALLOC_CTX *ctx = talloc_tos();814 char *buf = NULL;815 char *key = NULL;816 int len;817 TDB_DATA dbuf;818 int i;819 820 for (i=0;i<number;i++) {821 /* save index, so list is rebuilt in correct order */822 len = tdb_pack(NULL, 0, "dddddddd",823 i, (*list)[i].flag, (*list)[i].width, (*list)[i].length,824 (*list)[i].left, (*list)[i].top, (*list)[i].right,825 (*list)[i].bottom);826 if (!len) {827 continue;828 }829 buf = TALLOC_ARRAY(ctx, char, len);830 if (!buf) {831 return 0;832 }833 len = tdb_pack((uint8 *)buf, len, "dddddddd",834 i, (*list)[i].flag, (*list)[i].width, (*list)[i].length,835 (*list)[i].left, (*list)[i].top, (*list)[i].right,836 (*list)[i].bottom);837 key = talloc_asprintf(ctx, "%s%s", FORMS_PREFIX, (*list)[i].name);838 if (!key) {839 return 0;840 }841 dbuf.dsize = len;842 dbuf.dptr = (uint8 *)buf;843 if (tdb_store_bystring(tdb_forms, key, dbuf, TDB_REPLACE) != 0) {844 TALLOC_FREE(key);845 TALLOC_FREE(buf);846 break;847 }848 TALLOC_FREE(key);849 TALLOC_FREE(buf);850 }851 852 return i;853 }854 855 /****************************************************************************856 add a form struct at the end of the list857 ****************************************************************************/858 bool add_a_form(nt_forms_struct **list, struct spoolss_AddFormInfo1 *form, int *count)859 {860 int n=0;861 bool update;862 863 /*864 * NT tries to add forms even when865 * they are already in the base866 * only update the values if already present867 */868 869 update=False;870 871 for (n=0; n<*count; n++) {872 if ( strequal((*list)[n].name, form->form_name) ) {873 update=True;874 break;875 }876 }877 878 if (update==False) {879 if((*list=SMB_REALLOC_ARRAY(*list, nt_forms_struct, n+1)) == NULL) {880 DEBUG(0,("add_a_form: failed to enlarge forms list!\n"));881 return False;882 }883 fstrcpy((*list)[n].name, form->form_name);884 (*count)++;885 }886 887 (*list)[n].flag = form->flags;888 (*list)[n].width = form->size.width;889 (*list)[n].length = form->size.height;890 (*list)[n].left = form->area.left;891 (*list)[n].top = form->area.top;892 (*list)[n].right = form->area.right;893 (*list)[n].bottom = form->area.bottom;894 895 DEBUG(6,("add_a_form: Successfully %s form [%s]\n",896 update ? "updated" : "added", form->form_name));897 898 return True;899 }900 901 /****************************************************************************902 Delete a named form struct.903 ****************************************************************************/904 905 bool delete_a_form(nt_forms_struct **list, const char *del_name, int *count, WERROR *ret)906 {907 char *key = NULL;908 int n=0;909 910 *ret = WERR_OK;911 912 for (n=0; n<*count; n++) {913 if (!strncmp((*list)[n].name, del_name, strlen(del_name))) {914 DEBUG(103, ("delete_a_form, [%s] in list\n", del_name));915 break;916 }917 }918 919 if (n == *count) {920 DEBUG(10,("delete_a_form, [%s] not found\n", del_name));921 *ret = WERR_INVALID_PARAM;922 return False;923 }924 925 if (asprintf(&key, "%s%s", FORMS_PREFIX, (*list)[n].name) < 0) {926 *ret = WERR_NOMEM;927 return false;928 }929 if (tdb_delete_bystring(tdb_forms, key) != 0) {930 SAFE_FREE(key);931 *ret = WERR_NOMEM;932 return False;933 }934 SAFE_FREE(key);935 return true;936 }937 938 /****************************************************************************939 Update a form struct.940 ****************************************************************************/941 942 void update_a_form(nt_forms_struct **list, struct spoolss_AddFormInfo1 *form, int count)943 {944 int n=0;945 946 DEBUG(106, ("[%s]\n", form->form_name));947 for (n=0; n<count; n++) {948 DEBUGADD(106, ("n [%d]:[%s]\n", n, (*list)[n].name));949 if (!strncmp((*list)[n].name, form->form_name, strlen(form->form_name)))950 break;951 }952 953 if (n==count) return;954 955 (*list)[n].flag = form->flags;956 (*list)[n].width = form->size.width;957 (*list)[n].length = form->size.height;958 (*list)[n].left = form->area.left;959 (*list)[n].top = form->area.top;960 (*list)[n].right = form->area.right;961 (*list)[n].bottom = form->area.bottom;962 }963 964 /****************************************************************************965 Get the nt drivers list.966 Traverse the database and look-up the matching names.967 ****************************************************************************/968 int get_ntdrivers(fstring **list, const char *architecture, uint32 version)969 {970 int total=0;971 const char *short_archi;972 char *key = NULL;973 TDB_DATA kbuf, newkey;974 975 short_archi = get_short_archi(architecture);976 if (!short_archi) {977 return 0;978 }979 980 if (asprintf(&key, "%s%s/%d/", DRIVERS_PREFIX,981 short_archi, version) < 0) {982 return 0;983 }984 985 for (kbuf = tdb_firstkey(tdb_drivers);986 kbuf.dptr;987 newkey = tdb_nextkey(tdb_drivers, kbuf), free(kbuf.dptr), kbuf=newkey) {988 989 if (strncmp((const char *)kbuf.dptr, key, strlen(key)) != 0)990 continue;991 992 if((*list = SMB_REALLOC_ARRAY(*list, fstring, total+1)) == NULL) {993 DEBUG(0,("get_ntdrivers: failed to enlarge list!\n"));994 SAFE_FREE(key);995 return -1;996 }997 998 fstrcpy((*list)[total], (const char *)kbuf.dptr+strlen(key));999 total++;1000 }1001 1002 SAFE_FREE(key);1003 return(total);1004 }1005 1006 138 /**************************************************************************** 1007 139 Function to do the mapping between the long architecture name and … … 1013 145 int i=-1; 1014 146 1015 DEBUG(107,("Getting architecture depend ant directory\n"));147 DEBUG(107,("Getting architecture dependent directory\n")); 1016 148 do { 1017 149 i++; … … 1316 448 INTERNAL_OPEN_ONLY, /* oplock_request */ 1317 449 0, /* allocation_size */ 450 0, /* private_flags */ 1318 451 NULL, /* sd */ 1319 452 NULL, /* ea_list */ … … 1368 501 INTERNAL_OPEN_ONLY, /* oplock_request */ 1369 502 0, /* allocation_size */ 503 0, /* private_flags */ 1370 504 NULL, /* sd */ 1371 505 NULL, /* ea_list */ … … 1441 575 Determine the correct cVersion associated with an architecture and driver 1442 576 ****************************************************************************/ 1443 static uint32 get_correct_cversion(struct pipes_struct *p,577 static uint32 get_correct_cversion(struct auth_serversupplied_info *session_info, 1444 578 const char *architecture, 1445 579 const char *driverpath_in, 1446 580 WERROR *perr) 1447 581 { 1448 int cversion;582 int cversion = -1; 1449 583 NTSTATUS nt_status; 1450 584 struct smb_filename *smb_fname = NULL; … … 1452 586 files_struct *fsp = NULL; 1453 587 connection_struct *conn = NULL; 1454 NTSTATUS status;1455 588 char *oldcwd; 1456 fstring printdollar;589 char *printdollar = NULL; 1457 590 int printdollar_snum; 1458 591 … … 1473 606 } 1474 607 1475 fstrcpy(printdollar, "print$"); 1476 1477 printdollar_snum = find_service(printdollar); 608 printdollar_snum = find_service(talloc_tos(), "print$", &printdollar); 609 if (!printdollar) { 610 *perr = WERR_NOMEM; 611 return -1; 612 } 1478 613 if (printdollar_snum == -1) { 1479 614 *perr = WERR_NO_SUCH_SHARE; … … 1483 618 nt_status = create_conn_struct(talloc_tos(), &conn, printdollar_snum, 1484 619 lp_pathname(printdollar_snum), 1485 p->server_info, &oldcwd);620 session_info, &oldcwd); 1486 621 if (!NT_STATUS_IS_OK(nt_status)) { 1487 622 DEBUG(0,("get_correct_cversion: create_conn_struct " … … 1489 624 *perr = ntstatus_to_werror(nt_status); 1490 625 return -1; 626 } 627 628 nt_status = set_conn_force_user_group(conn, printdollar_snum); 629 if (!NT_STATUS_IS_OK(nt_status)) { 630 DEBUG(0, ("failed set force user / group\n")); 631 *perr = ntstatus_to_werror(nt_status); 632 goto error_free_conn; 633 } 634 635 if (!become_user_by_session(conn, session_info)) { 636 DEBUG(0, ("failed to become user\n")); 637 *perr = WERR_ACCESS_DENIED; 638 goto error_free_conn; 1491 639 } 1492 640 … … 1510 658 nt_status = vfs_file_exist(conn, smb_fname); 1511 659 if (!NT_STATUS_IS_OK(nt_status)) { 660 DEBUG(3,("get_correct_cversion: vfs_file_exist failed\n")); 1512 661 *perr = WERR_BADFILE; 1513 662 goto error_exit; 1514 663 } 1515 664 1516 status = SMB_VFS_CREATE_FILE(665 nt_status = SMB_VFS_CREATE_FILE( 1517 666 conn, /* conn */ 1518 667 NULL, /* req */ … … 1525 674 FILE_ATTRIBUTE_NORMAL, /* file_attributes */ 1526 675 INTERNAL_OPEN_ONLY, /* oplock_request */ 676 0, /* private_flags */ 1527 677 0, /* allocation_size */ 1528 678 NULL, /* sd */ … … 1531 681 NULL); /* pinfo */ 1532 682 1533 if (!NT_STATUS_IS_OK( status)) {683 if (!NT_STATUS_IS_OK(nt_status)) { 1534 684 DEBUG(3,("get_correct_cversion: Can't open file [%s], errno = " 1535 685 "%d\n", smb_fname_str_dbg(smb_fname), errno)); … … 1542 692 1543 693 ret = get_file_version(fsp, smb_fname->base_name, &major, &minor); 1544 if (ret == -1) goto error_exit; 1545 1546 if (!ret) { 694 if (ret == -1) { 695 *perr = WERR_INVALID_PARAM; 696 goto error_exit; 697 } else if (!ret) { 1547 698 DEBUG(6,("get_correct_cversion: Version info not " 1548 699 "found [%s]\n", 1549 700 smb_fname_str_dbg(smb_fname))); 701 *perr = WERR_INVALID_PARAM; 1550 702 goto error_exit; 1551 703 } … … 1579 731 DEBUG(10,("get_correct_cversion: Driver file [%s] cversion = %d\n", 1580 732 smb_fname_str_dbg(smb_fname), cversion)); 1581 1582 goto done; 733 *perr = WERR_OK; 1583 734 1584 735 error_exit: 1585 cversion = -1;1586 done:736 unbecome_user(); 737 error_free_conn: 1587 738 TALLOC_FREE(smb_fname); 1588 739 if (fsp != NULL) { … … 1591 742 if (conn != NULL) { 1592 743 vfs_ChDir(conn, oldcwd); 744 SMB_VFS_DISCONNECT(conn); 1593 745 conn_free(conn); 1594 746 } 1595 if (cversion != -1) { 1596 *perr = WERR_OK; 1597 } 747 if (!NT_STATUS_IS_OK(*perr)) { 748 cversion = -1; 749 } 750 1598 751 return cversion; 1599 752 } … … 1610 763 1611 764 static WERROR clean_up_driver_struct_level(TALLOC_CTX *mem_ctx, 1612 struct pipes_struct *rpc_pipe,765 struct auth_serversupplied_info *session_info, 1613 766 const char *architecture, 1614 767 const char **driver_path, … … 1617 770 const char **help_file, 1618 771 struct spoolss_StringArray *dependent_files, 1619 uint32_t*version)772 enum spoolss_DriverOSVersion *version) 1620 773 { 1621 774 const char *short_architecture; … … 1670 823 */ 1671 824 1672 *version = get_correct_cversion( rpc_pipe, short_architecture,825 *version = get_correct_cversion(session_info, short_architecture, 1673 826 *driver_path, &err); 1674 827 if (*version == -1) { … … 1682 835 ****************************************************************************/ 1683 836 1684 WERROR clean_up_driver_struct(struct pipes_struct *rpc_pipe, 837 WERROR clean_up_driver_struct(TALLOC_CTX *mem_ctx, 838 struct auth_serversupplied_info *session_info, 1685 839 struct spoolss_AddDriverInfoCtr *r) 1686 840 { 1687 841 switch (r->level) { 1688 842 case 3: 1689 return clean_up_driver_struct_level( r, rpc_pipe,843 return clean_up_driver_struct_level(mem_ctx, session_info, 1690 844 r->info.info3->architecture, 1691 845 &r->info.info3->driver_path, … … 1696 850 &r->info.info3->version); 1697 851 case 6: 1698 return clean_up_driver_struct_level( r, rpc_pipe,852 return clean_up_driver_struct_level(mem_ctx, session_info, 1699 853 r->info.info6->architecture, 1700 854 &r->info.info6->driver_path, … … 1731 885 1732 886 /**************************************************************************** 1733 This function sucks and should be replaced. JRA.1734 ****************************************************************************/1735 1736 static void convert_level_8_to_level3(TALLOC_CTX *mem_ctx,1737 struct spoolss_AddDriverInfo3 *dst,1738 const struct spoolss_DriverInfo8 *src)1739 {1740 dst->version = src->version;1741 dst->driver_name = src->driver_name;1742 dst->architecture = src->architecture;1743 dst->driver_path = src->driver_path;1744 dst->data_file = src->data_file;1745 dst->config_file = src->config_file;1746 dst->help_file = src->help_file;1747 dst->monitor_name = src->monitor_name;1748 dst->default_datatype = src->default_datatype;1749 if (src->dependent_files) {1750 dst->dependent_files = talloc_zero(mem_ctx, struct spoolss_StringArray);1751 if (!dst->dependent_files) return;1752 dst->dependent_files->string = src->dependent_files;1753 } else {1754 dst->dependent_files = NULL;1755 }1756 }1757 1758 /****************************************************************************1759 887 ****************************************************************************/ 1760 888 … … 1827 955 } 1828 956 1829 WERROR move_driver_to_download_area(struct pipes_struct *p, 1830 struct spoolss_AddDriverInfoCtr *r, 1831 WERROR *perr) 957 WERROR move_driver_to_download_area(struct auth_serversupplied_info *session_info, 958 struct spoolss_AddDriverInfoCtr *r) 1832 959 { 1833 960 struct spoolss_AddDriverInfo3 *driver; … … 1842 969 int ver = 0; 1843 970 char *oldcwd; 1844 fstring printdollar;971 char *printdollar = NULL; 1845 972 int printdollar_snum; 1846 1847 *perr = WERR_OK; 973 WERROR err = WERR_OK; 1848 974 1849 975 switch (r->level) { … … 1865 991 } 1866 992 1867 fstrcpy(printdollar, "print$"); 1868 1869 printdollar_snum = find_service(printdollar); 993 printdollar_snum = find_service(ctx, "print$", &printdollar); 994 if (!printdollar) { 995 return WERR_NOMEM; 996 } 1870 997 if (printdollar_snum == -1) { 1871 *perr = WERR_NO_SUCH_SHARE;1872 998 return WERR_NO_SUCH_SHARE; 1873 999 } … … 1875 1001 nt_status = create_conn_struct(talloc_tos(), &conn, printdollar_snum, 1876 1002 lp_pathname(printdollar_snum), 1877 p->server_info, &oldcwd);1003 session_info, &oldcwd); 1878 1004 if (!NT_STATUS_IS_OK(nt_status)) { 1879 1005 DEBUG(0,("move_driver_to_download_area: create_conn_struct " 1880 1006 "returned %s\n", nt_errstr(nt_status))); 1881 *perr = ntstatus_to_werror(nt_status); 1882 return *perr; 1007 err = ntstatus_to_werror(nt_status); 1008 return err; 1009 } 1010 1011 nt_status = set_conn_force_user_group(conn, printdollar_snum); 1012 if (!NT_STATUS_IS_OK(nt_status)) { 1013 DEBUG(0, ("failed set force user / group\n")); 1014 err = ntstatus_to_werror(nt_status); 1015 goto err_free_conn; 1016 } 1017 1018 if (!become_user_by_session(conn, session_info)) { 1019 DEBUG(0, ("failed to become user\n")); 1020 err = WERR_ACCESS_DENIED; 1021 goto err_free_conn; 1883 1022 } 1884 1023 … … 1888 1027 driver->version); 1889 1028 if (!new_dir) { 1890 *perr = WERR_NOMEM;1029 err = WERR_NOMEM; 1891 1030 goto err_exit; 1892 1031 } 1893 1032 nt_status = driver_unix_convert(conn, new_dir, &smb_dname); 1894 1033 if (!NT_STATUS_IS_OK(nt_status)) { 1895 *perr = WERR_NOMEM;1034 err = WERR_NOMEM; 1896 1035 goto err_exit; 1897 1036 } … … 1899 1038 DEBUG(5,("Creating first directory: %s\n", smb_dname->base_name)); 1900 1039 1901 create_directory(conn, NULL, smb_dname); 1040 nt_status = create_directory(conn, NULL, smb_dname); 1041 if (!NT_STATUS_IS_OK(nt_status) 1042 && !NT_STATUS_EQUAL(nt_status, NT_STATUS_OBJECT_NAME_COLLISION)) { 1043 DEBUG(0, ("failed to create driver destination directory: %s\n", 1044 nt_errstr(nt_status))); 1045 err = ntstatus_to_werror(nt_status); 1046 goto err_exit; 1047 } 1902 1048 1903 1049 /* For each driver file, archi\filexxx.yyy, if there is a duplicate file … … 1922 1068 if (driver->driver_path && strlen(driver->driver_path)) { 1923 1069 1924 *perr = move_driver_file_to_download_area(ctx, 1925 conn, 1926 driver->driver_path, 1927 short_architecture, 1928 driver->version, 1929 ver); 1930 if (!W_ERROR_IS_OK(*perr)) { 1931 if (W_ERROR_EQUAL(*perr, WERR_ACCESS_DENIED)) { 1932 ver = -1; 1933 } 1070 err = move_driver_file_to_download_area(ctx, 1071 conn, 1072 driver->driver_path, 1073 short_architecture, 1074 driver->version, 1075 ver); 1076 if (!W_ERROR_IS_OK(err)) { 1934 1077 goto err_exit; 1935 1078 } … … 1939 1082 if (!strequal(driver->data_file, driver->driver_path)) { 1940 1083 1941 *perr = move_driver_file_to_download_area(ctx, 1942 conn, 1943 driver->data_file, 1944 short_architecture, 1945 driver->version, 1946 ver); 1947 if (!W_ERROR_IS_OK(*perr)) { 1948 if (W_ERROR_EQUAL(*perr, WERR_ACCESS_DENIED)) { 1949 ver = -1; 1950 } 1084 err = move_driver_file_to_download_area(ctx, 1085 conn, 1086 driver->data_file, 1087 short_architecture, 1088 driver->version, 1089 ver); 1090 if (!W_ERROR_IS_OK(err)) { 1951 1091 goto err_exit; 1952 1092 } … … 1958 1098 !strequal(driver->config_file, driver->data_file)) { 1959 1099 1960 *perr = move_driver_file_to_download_area(ctx, 1961 conn, 1962 driver->config_file, 1963 short_architecture, 1964 driver->version, 1965 ver); 1966 if (!W_ERROR_IS_OK(*perr)) { 1967 if (W_ERROR_EQUAL(*perr, WERR_ACCESS_DENIED)) { 1968 ver = -1; 1969 } 1100 err = move_driver_file_to_download_area(ctx, 1101 conn, 1102 driver->config_file, 1103 short_architecture, 1104 driver->version, 1105 ver); 1106 if (!W_ERROR_IS_OK(err)) { 1970 1107 goto err_exit; 1971 1108 } … … 1978 1115 !strequal(driver->help_file, driver->config_file)) { 1979 1116 1980 *perr = move_driver_file_to_download_area(ctx, 1981 conn, 1982 driver->help_file, 1983 short_architecture, 1984 driver->version, 1985 ver); 1986 if (!W_ERROR_IS_OK(*perr)) { 1987 if (W_ERROR_EQUAL(*perr, WERR_ACCESS_DENIED)) { 1988 ver = -1; 1989 } 1117 err = move_driver_file_to_download_area(ctx, 1118 conn, 1119 driver->help_file, 1120 short_architecture, 1121 driver->version, 1122 ver); 1123 if (!W_ERROR_IS_OK(err)) { 1990 1124 goto err_exit; 1991 1125 } … … 2006 1140 } 2007 1141 2008 *perr = move_driver_file_to_download_area(ctx, 2009 conn, 2010 driver->dependent_files->string[i], 2011 short_architecture, 2012 driver->version, 2013 ver); 2014 if (!W_ERROR_IS_OK(*perr)) { 2015 if (W_ERROR_EQUAL(*perr, WERR_ACCESS_DENIED)) { 2016 ver = -1; 2017 } 1142 err = move_driver_file_to_download_area(ctx, 1143 conn, 1144 driver->dependent_files->string[i], 1145 short_architecture, 1146 driver->version, 1147 ver); 1148 if (!W_ERROR_IS_OK(err)) { 2018 1149 goto err_exit; 2019 1150 } … … 2023 1154 } 2024 1155 2025 err_exit: 1156 err = WERR_OK; 1157 err_exit: 1158 unbecome_user(); 1159 err_free_conn: 2026 1160 TALLOC_FREE(smb_dname); 2027 1161 2028 1162 if (conn != NULL) { 2029 1163 vfs_ChDir(conn, oldcwd); 1164 SMB_VFS_DISCONNECT(conn); 2030 1165 conn_free(conn); 2031 1166 } 2032 1167 2033 if (W_ERROR_EQUAL(*perr, WERR_OK)) { 2034 return WERR_OK; 2035 } 2036 if (ver == -1) { 2037 return WERR_UNKNOWN_PRINTER_DRIVER; 2038 } 2039 return (*perr); 2040 } 2041 2042 /**************************************************************************** 2043 ****************************************************************************/ 2044 2045 static uint32 add_a_printer_driver_3(struct spoolss_AddDriverInfo3 *driver) 2046 { 2047 TALLOC_CTX *ctx = talloc_tos(); 2048 int len, buflen; 2049 const char *architecture; 2050 char *directory = NULL; 2051 char *key = NULL; 2052 uint8 *buf; 2053 int i, ret; 2054 TDB_DATA dbuf; 2055 2056 architecture = get_short_archi(driver->architecture); 2057 if (!architecture) { 2058 return (uint32)-1; 2059 } 2060 2061 /* The names are relative. We store them in the form: \print$\arch\version\driver.xxx 2062 * \\server is added in the rpc server layer. 2063 * It does make sense to NOT store the server's name in the printer TDB. 2064 */ 2065 2066 directory = talloc_asprintf(ctx, "\\print$\\%s\\%d\\", 2067 architecture, driver->version); 2068 if (!directory) { 2069 return (uint32)-1; 2070 } 2071 2072 #define gen_full_driver_unc_path(ctx, directory, file) \ 2073 do { \ 2074 if (file && strlen(file)) { \ 2075 file = talloc_asprintf(ctx, "%s%s", directory, file); \ 2076 } else { \ 2077 file = talloc_strdup(ctx, ""); \ 2078 } \ 2079 if (!file) { \ 2080 return (uint32_t)-1; \ 2081 } \ 2082 } while (0); 2083 2084 /* .inf files do not always list a file for each of the four standard files. 2085 * Don't prepend a path to a null filename, or client claims: 2086 * "The server on which the printer resides does not have a suitable 2087 * <printer driver name> printer driver installed. Click OK if you 2088 * wish to install the driver on your local machine." 2089 */ 2090 2091 gen_full_driver_unc_path(ctx, directory, driver->driver_path); 2092 gen_full_driver_unc_path(ctx, directory, driver->data_file); 2093 gen_full_driver_unc_path(ctx, directory, driver->config_file); 2094 gen_full_driver_unc_path(ctx, directory, driver->help_file); 2095 2096 if (driver->dependent_files && driver->dependent_files->string) { 2097 for (i=0; driver->dependent_files->string[i]; i++) { 2098 gen_full_driver_unc_path(ctx, directory, 2099 driver->dependent_files->string[i]); 2100 } 2101 } 2102 2103 key = talloc_asprintf(ctx, "%s%s/%d/%s", DRIVERS_PREFIX, 2104 architecture, driver->version, driver->driver_name); 2105 if (!key) { 2106 return (uint32)-1; 2107 } 2108 2109 DEBUG(5,("add_a_printer_driver_3: Adding driver with key %s\n", key )); 2110 2111 buf = NULL; 2112 len = buflen = 0; 2113 2114 again: 2115 len = 0; 2116 len += tdb_pack(buf+len, buflen-len, "dffffffff", 2117 driver->version, 2118 driver->driver_name, 2119 driver->architecture, 2120 driver->driver_path, 2121 driver->data_file, 2122 driver->config_file, 2123 driver->help_file, 2124 driver->monitor_name ? driver->monitor_name : "", 2125 driver->default_datatype ? driver->default_datatype : ""); 2126 2127 if (driver->dependent_files && driver->dependent_files->string) { 2128 for (i=0; driver->dependent_files->string[i]; i++) { 2129 len += tdb_pack(buf+len, buflen-len, "f", 2130 driver->dependent_files->string[i]); 2131 } 2132 } 2133 2134 if (len != buflen) { 2135 buf = (uint8 *)SMB_REALLOC(buf, len); 2136 if (!buf) { 2137 DEBUG(0,("add_a_printer_driver_3: failed to enlarge buffer\n!")); 2138 ret = -1; 2139 goto done; 2140 } 2141 buflen = len; 2142 goto again; 2143 } 2144 2145 dbuf.dptr = buf; 2146 dbuf.dsize = len; 2147 2148 ret = tdb_store_bystring(tdb_drivers, key, dbuf, TDB_REPLACE); 2149 2150 done: 2151 if (ret) 2152 DEBUG(0,("add_a_printer_driver_3: Adding driver with key %s failed.\n", key )); 2153 2154 SAFE_FREE(buf); 2155 return ret; 2156 } 2157 2158 /**************************************************************************** 2159 ****************************************************************************/ 2160 2161 static uint32_t add_a_printer_driver_8(struct spoolss_DriverInfo8 *driver) 2162 { 2163 TALLOC_CTX *mem_ctx = talloc_new(talloc_tos()); 2164 struct spoolss_AddDriverInfo3 info3; 2165 uint32_t ret; 2166 2167 convert_level_8_to_level3(mem_ctx, &info3, driver); 2168 2169 ret = add_a_printer_driver_3(&info3); 2170 talloc_free(mem_ctx); 2171 2172 return ret; 2173 } 2174 2175 /**************************************************************************** 2176 ****************************************************************************/ 2177 2178 static WERROR get_a_printer_driver_3_default(TALLOC_CTX *mem_ctx, 2179 struct spoolss_DriverInfo3 *info, 2180 const char *driver, const char *arch) 2181 { 2182 info->driver_name = talloc_strdup(mem_ctx, driver); 2183 if (!info->driver_name) { 2184 return WERR_NOMEM; 2185 } 2186 2187 info->default_datatype = talloc_strdup(mem_ctx, "RAW"); 2188 if (!info->default_datatype) { 2189 return WERR_NOMEM; 2190 } 2191 2192 info->driver_path = talloc_strdup(mem_ctx, ""); 2193 info->data_file = talloc_strdup(mem_ctx, ""); 2194 info->config_file = talloc_strdup(mem_ctx, ""); 2195 info->help_file = talloc_strdup(mem_ctx, ""); 2196 if (!info->driver_path || !info->data_file || !info->config_file || !info->help_file) { 2197 return WERR_NOMEM; 2198 } 2199 2200 return WERR_OK; 2201 } 2202 2203 /**************************************************************************** 2204 ****************************************************************************/ 2205 2206 static WERROR get_a_printer_driver_3(TALLOC_CTX *mem_ctx, 2207 struct spoolss_DriverInfo3 *driver, 2208 const char *drivername, const char *arch, 2209 uint32_t version) 2210 { 2211 TDB_DATA dbuf; 2212 const char *architecture; 2213 int len = 0; 2214 int i; 2215 char *key = NULL; 2216 fstring name, driverpath, environment, datafile, configfile, helpfile, monitorname, defaultdatatype; 2217 2218 architecture = get_short_archi(arch); 2219 if ( !architecture ) { 2220 return WERR_UNKNOWN_PRINTER_DRIVER; 2221 } 2222 2223 /* Windows 4.0 (i.e. win9x) should always use a version of 0 */ 2224 2225 if ( strcmp( architecture, SPL_ARCH_WIN40 ) == 0 ) 2226 version = 0; 2227 2228 DEBUG(8,("get_a_printer_driver_3: [%s%s/%d/%s]\n", DRIVERS_PREFIX, architecture, version, drivername)); 2229 2230 if (asprintf(&key, "%s%s/%d/%s", DRIVERS_PREFIX, 2231 architecture, version, drivername) < 0) { 2232 return WERR_NOMEM; 2233 } 2234 2235 dbuf = tdb_fetch_bystring(tdb_drivers, key); 2236 if (!dbuf.dptr) { 2237 SAFE_FREE(key); 2238 return WERR_UNKNOWN_PRINTER_DRIVER; 2239 } 2240 2241 len += tdb_unpack(dbuf.dptr, dbuf.dsize, "dffffffff", 2242 &driver->version, 2243 name, 2244 environment, 2245 driverpath, 2246 datafile, 2247 configfile, 2248 helpfile, 2249 monitorname, 2250 defaultdatatype); 2251 2252 driver->driver_name = talloc_strdup(mem_ctx, name); 2253 driver->architecture = talloc_strdup(mem_ctx, environment); 2254 driver->driver_path = talloc_strdup(mem_ctx, driverpath); 2255 driver->data_file = talloc_strdup(mem_ctx, datafile); 2256 driver->config_file = talloc_strdup(mem_ctx, configfile); 2257 driver->help_file = talloc_strdup(mem_ctx, helpfile); 2258 driver->monitor_name = talloc_strdup(mem_ctx, monitorname); 2259 driver->default_datatype = talloc_strdup(mem_ctx, defaultdatatype); 2260 2261 i=0; 2262 2263 while (len < dbuf.dsize) { 2264 2265 fstring file; 2266 2267 driver->dependent_files = talloc_realloc(mem_ctx, driver->dependent_files, const char *, i+2); 2268 if (!driver->dependent_files ) { 2269 DEBUG(0,("get_a_printer_driver_3: failed to enlarge buffer!\n")); 2270 break; 2271 } 2272 2273 len += tdb_unpack(dbuf.dptr+len, dbuf.dsize-len, "f", 2274 &file); 2275 2276 driver->dependent_files[i] = talloc_strdup(mem_ctx, file); 2277 2278 i++; 2279 } 2280 2281 if (driver->dependent_files) 2282 driver->dependent_files[i] = NULL; 2283 2284 SAFE_FREE(dbuf.dptr); 2285 SAFE_FREE(key); 2286 2287 if (len != dbuf.dsize) { 2288 return get_a_printer_driver_3_default(mem_ctx, driver, drivername, arch); 2289 } 2290 2291 return WERR_OK; 2292 } 2293 2294 /**************************************************************************** 2295 ****************************************************************************/ 2296 int pack_devicemode(NT_DEVICEMODE *nt_devmode, uint8 *buf, int buflen) 2297 { 2298 int len = 0; 2299 2300 len += tdb_pack(buf+len, buflen-len, "p", nt_devmode); 2301 2302 if (!nt_devmode) 2303 return len; 2304 2305 len += tdb_pack(buf+len, buflen-len, "ffwwwwwwwwwwwwwwwwwwddddddddddddddp", 2306 nt_devmode->devicename, 2307 nt_devmode->formname, 2308 2309 nt_devmode->specversion, 2310 nt_devmode->driverversion, 2311 nt_devmode->size, 2312 nt_devmode->driverextra, 2313 nt_devmode->orientation, 2314 nt_devmode->papersize, 2315 nt_devmode->paperlength, 2316 nt_devmode->paperwidth, 2317 nt_devmode->scale, 2318 nt_devmode->copies, 2319 nt_devmode->defaultsource, 2320 nt_devmode->printquality, 2321 nt_devmode->color, 2322 nt_devmode->duplex, 2323 nt_devmode->yresolution, 2324 nt_devmode->ttoption, 2325 nt_devmode->collate, 2326 nt_devmode->logpixels, 2327 2328 nt_devmode->fields, 2329 nt_devmode->bitsperpel, 2330 nt_devmode->pelswidth, 2331 nt_devmode->pelsheight, 2332 nt_devmode->displayflags, 2333 nt_devmode->displayfrequency, 2334 nt_devmode->icmmethod, 2335 nt_devmode->icmintent, 2336 nt_devmode->mediatype, 2337 nt_devmode->dithertype, 2338 nt_devmode->reserved1, 2339 nt_devmode->reserved2, 2340 nt_devmode->panningwidth, 2341 nt_devmode->panningheight, 2342 nt_devmode->nt_dev_private); 2343 2344 if (nt_devmode->nt_dev_private) { 2345 len += tdb_pack(buf+len, buflen-len, "B", 2346 nt_devmode->driverextra, 2347 nt_devmode->nt_dev_private); 2348 } 2349 2350 DEBUG(8,("Packed devicemode [%s]\n", nt_devmode->formname)); 2351 2352 return len; 2353 } 2354 2355 /**************************************************************************** 2356 Pack all values in all printer keys 2357 ***************************************************************************/ 2358 2359 static int pack_values(NT_PRINTER_DATA *data, uint8 *buf, int buflen) 2360 { 2361 int len = 0; 2362 int i, j; 2363 struct regval_blob *val; 2364 struct regval_ctr *val_ctr; 2365 char *path = NULL; 2366 int num_values; 2367 2368 if ( !data ) 2369 return 0; 2370 2371 /* loop over all keys */ 2372 2373 for ( i=0; i<data->num_keys; i++ ) { 2374 val_ctr = data->keys[i].values; 2375 num_values = regval_ctr_numvals( val_ctr ); 2376 2377 /* pack the keyname followed by a empty value */ 2378 2379 len += tdb_pack(buf+len, buflen-len, "pPdB", 2380 &data->keys[i].name, 2381 data->keys[i].name, 2382 REG_NONE, 2383 0, 2384 NULL); 2385 2386 /* now loop over all values */ 2387 2388 for ( j=0; j<num_values; j++ ) { 2389 /* pathname should be stored as <key>\<value> */ 2390 2391 val = regval_ctr_specific_value( val_ctr, j ); 2392 if (asprintf(&path, "%s\\%s", 2393 data->keys[i].name, 2394 regval_name(val)) < 0) { 2395 return -1; 2396 } 2397 2398 len += tdb_pack(buf+len, buflen-len, "pPdB", 2399 val, 2400 path, 2401 regval_type(val), 2402 regval_size(val), 2403 regval_data_p(val) ); 2404 2405 DEBUG(8,("specific: [%s], len: %d\n", regval_name(val), regval_size(val))); 2406 SAFE_FREE(path); 2407 } 2408 2409 } 2410 2411 /* terminator */ 2412 2413 len += tdb_pack(buf+len, buflen-len, "p", NULL); 2414 2415 return len; 2416 } 2417 2418 2419 /**************************************************************************** 2420 Delete a printer - this just deletes the printer info file, any open 2421 handles are not affected. 2422 ****************************************************************************/ 2423 2424 uint32 del_a_printer(const char *sharename) 2425 { 2426 TDB_DATA kbuf; 2427 char *printdb_path = NULL; 2428 TALLOC_CTX *ctx = talloc_tos(); 2429 2430 kbuf = make_printer_tdbkey(ctx, sharename); 2431 tdb_delete(tdb_printers, kbuf); 2432 2433 kbuf= make_printers_secdesc_tdbkey(ctx, sharename); 2434 tdb_delete(tdb_printers, kbuf); 2435 2436 close_all_print_db(); 2437 2438 if (geteuid() == sec_initial_uid()) { 2439 if (asprintf(&printdb_path, "%s%s.tdb", 2440 cache_path("printing/"), 2441 sharename) < 0) { 2442 return (uint32)-1; 2443 } 2444 unlink(printdb_path); 2445 SAFE_FREE(printdb_path); 2446 } 2447 2448 return 0; 2449 } 2450 2451 /**************************************************************************** 2452 ****************************************************************************/ 2453 static WERROR update_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info) 2454 { 2455 uint8 *buf; 2456 int buflen, len; 2457 int retlen; 2458 WERROR ret; 2459 TDB_DATA kbuf, dbuf; 2460 2461 /* 2462 * in addprinter: no servername and the printer is the name 2463 * in setprinter: servername is \\server 2464 * and printer is \\server\\printer 2465 * 2466 * Samba manages only local printers. 2467 * we currently don't support things like i 2468 * path=\\other_server\printer 2469 * 2470 * We only store the printername, not \\server\printername 2471 */ 2472 2473 if ( info->servername[0] != '\0' ) { 2474 trim_string(info->printername, info->servername, NULL); 2475 trim_char(info->printername, '\\', '\0'); 2476 info->servername[0]='\0'; 2477 } 2478 2479 /* 2480 * JFM: one day I'll forget. 2481 * below that's info->portname because that's the SAMBA sharename 2482 * and I made NT 'thinks' it's the portname 2483 * the info->sharename is the thing you can name when you add a printer 2484 * that's the short-name when you create shared printer for 95/98 2485 * So I've made a limitation in SAMBA: you can only have 1 printer model 2486 * behind a SAMBA share. 2487 */ 2488 2489 buf = NULL; 2490 buflen = 0; 2491 2492 again: 2493 len = 0; 2494 len += tdb_pack(buf+len, buflen-len, "dddddddddddfffffPfffff", 2495 info->attributes, 2496 info->priority, 2497 info->default_priority, 2498 info->starttime, 2499 info->untiltime, 2500 info->status, 2501 info->cjobs, 2502 info->averageppm, 2503 info->changeid, 2504 info->c_setprinter, 2505 info->setuptime, 2506 info->servername, 2507 info->printername, 2508 info->sharename, 2509 info->portname, 2510 info->drivername, 2511 info->comment, 2512 info->location, 2513 info->sepfile, 2514 info->printprocessor, 2515 info->datatype, 2516 info->parameters); 2517 2518 len += pack_devicemode(info->devmode, buf+len, buflen-len); 2519 retlen = pack_values( info->data, buf+len, buflen-len ); 2520 if (retlen == -1) { 2521 ret = WERR_NOMEM; 2522 goto done; 2523 } 2524 len += retlen; 2525 2526 if (buflen != len) { 2527 buf = (uint8 *)SMB_REALLOC(buf, len); 2528 if (!buf) { 2529 DEBUG(0,("update_a_printer_2: failed to enlarge buffer!\n")); 2530 ret = WERR_NOMEM; 2531 goto done; 2532 } 2533 buflen = len; 2534 goto again; 2535 } 2536 2537 kbuf = make_printer_tdbkey(talloc_tos(), info->sharename ); 2538 2539 dbuf.dptr = buf; 2540 dbuf.dsize = len; 2541 2542 ret = (tdb_store(tdb_printers, kbuf, dbuf, TDB_REPLACE) == 0? WERR_OK : WERR_NOMEM); 2543 2544 done: 2545 if (!W_ERROR_IS_OK(ret)) 2546 DEBUG(8, ("error updating printer to tdb on disk\n")); 2547 2548 SAFE_FREE(buf); 2549 2550 DEBUG(8,("packed printer [%s] with driver [%s] portname=[%s] len=%d\n", 2551 info->sharename, info->drivername, info->portname, len)); 2552 2553 return ret; 2554 } 2555 2556 2557 /**************************************************************************** 2558 Malloc and return an NT devicemode. 2559 ****************************************************************************/ 2560 2561 NT_DEVICEMODE *construct_nt_devicemode(const fstring default_devicename) 2562 { 2563 2564 char adevice[MAXDEVICENAME]; 2565 NT_DEVICEMODE *nt_devmode = SMB_MALLOC_P(NT_DEVICEMODE); 2566 2567 if (nt_devmode == NULL) { 2568 DEBUG(0,("construct_nt_devicemode: malloc fail.\n")); 2569 return NULL; 2570 } 2571 2572 ZERO_STRUCTP(nt_devmode); 2573 2574 slprintf(adevice, sizeof(adevice), "%s", default_devicename); 2575 fstrcpy(nt_devmode->devicename, adevice); 2576 2577 fstrcpy(nt_devmode->formname, "Letter"); 2578 2579 nt_devmode->specversion = DMSPEC_NT4_AND_ABOVE; 2580 nt_devmode->driverversion = 0x0400; 2581 nt_devmode->size = 0x00DC; 2582 nt_devmode->driverextra = 0x0000; 2583 nt_devmode->fields = DEVMODE_FORMNAME | 2584 DEVMODE_TTOPTION | 2585 DEVMODE_PRINTQUALITY | 2586 DEVMODE_DEFAULTSOURCE | 2587 DEVMODE_COPIES | 2588 DEVMODE_SCALE | 2589 DEVMODE_PAPERSIZE | 2590 DEVMODE_ORIENTATION; 2591 nt_devmode->orientation = DMORIENT_PORTRAIT; 2592 nt_devmode->papersize = DMPAPER_LETTER; 2593 nt_devmode->paperlength = 0; 2594 nt_devmode->paperwidth = 0; 2595 nt_devmode->scale = 0x64; 2596 nt_devmode->copies = 1; 2597 nt_devmode->defaultsource = DMBIN_FORMSOURCE; 2598 nt_devmode->printquality = DMRES_HIGH; /* 0x0258 */ 2599 nt_devmode->color = DMRES_MONOCHROME; 2600 nt_devmode->duplex = DMDUP_SIMPLEX; 2601 nt_devmode->yresolution = 0; 2602 nt_devmode->ttoption = DMTT_SUBDEV; 2603 nt_devmode->collate = DMCOLLATE_FALSE; 2604 nt_devmode->icmmethod = 0; 2605 nt_devmode->icmintent = 0; 2606 nt_devmode->mediatype = 0; 2607 nt_devmode->dithertype = 0; 2608 2609 /* non utilisés par un driver d'imprimante */ 2610 nt_devmode->logpixels = 0; 2611 nt_devmode->bitsperpel = 0; 2612 nt_devmode->pelswidth = 0; 2613 nt_devmode->pelsheight = 0; 2614 nt_devmode->displayflags = 0; 2615 nt_devmode->displayfrequency = 0; 2616 nt_devmode->reserved1 = 0; 2617 nt_devmode->reserved2 = 0; 2618 nt_devmode->panningwidth = 0; 2619 nt_devmode->panningheight = 0; 2620 2621 nt_devmode->nt_dev_private = NULL; 2622 return nt_devmode; 2623 } 2624 2625 /**************************************************************************** 2626 Clean up and deallocate a (maybe partially) allocated NT_DEVICEMODE. 2627 ****************************************************************************/ 2628 2629 void free_nt_devicemode(NT_DEVICEMODE **devmode_ptr) 2630 { 2631 NT_DEVICEMODE *nt_devmode = *devmode_ptr; 2632 2633 if(nt_devmode == NULL) 2634 return; 2635 2636 DEBUG(106,("free_nt_devicemode: deleting DEVMODE\n")); 2637 2638 SAFE_FREE(nt_devmode->nt_dev_private); 2639 SAFE_FREE(*devmode_ptr); 2640 } 2641 2642 /**************************************************************************** 2643 Clean up and deallocate a (maybe partially) allocated NT_PRINTER_INFO_LEVEL_2. 2644 ****************************************************************************/ 2645 2646 static void free_nt_printer_info_level_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr) 2647 { 2648 NT_PRINTER_INFO_LEVEL_2 *info = *info_ptr; 2649 2650 if ( !info ) 2651 return; 2652 2653 free_nt_devicemode(&info->devmode); 2654 2655 TALLOC_FREE( *info_ptr ); 2656 } 2657 2658 2659 /**************************************************************************** 2660 ****************************************************************************/ 2661 int unpack_devicemode(NT_DEVICEMODE **nt_devmode, const uint8 *buf, int buflen) 2662 { 2663 int len = 0; 2664 int extra_len = 0; 2665 NT_DEVICEMODE devmode; 2666 2667 ZERO_STRUCT(devmode); 2668 2669 len += tdb_unpack(buf+len, buflen-len, "p", nt_devmode); 2670 2671 if (!*nt_devmode) return len; 2672 2673 len += tdb_unpack(buf+len, buflen-len, "ffwwwwwwwwwwwwwwwwwwddddddddddddddp", 2674 devmode.devicename, 2675 devmode.formname, 2676 2677 &devmode.specversion, 2678 &devmode.driverversion, 2679 &devmode.size, 2680 &devmode.driverextra, 2681 &devmode.orientation, 2682 &devmode.papersize, 2683 &devmode.paperlength, 2684 &devmode.paperwidth, 2685 &devmode.scale, 2686 &devmode.copies, 2687 &devmode.defaultsource, 2688 &devmode.printquality, 2689 &devmode.color, 2690 &devmode.duplex, 2691 &devmode.yresolution, 2692 &devmode.ttoption, 2693 &devmode.collate, 2694 &devmode.logpixels, 2695 2696 &devmode.fields, 2697 &devmode.bitsperpel, 2698 &devmode.pelswidth, 2699 &devmode.pelsheight, 2700 &devmode.displayflags, 2701 &devmode.displayfrequency, 2702 &devmode.icmmethod, 2703 &devmode.icmintent, 2704 &devmode.mediatype, 2705 &devmode.dithertype, 2706 &devmode.reserved1, 2707 &devmode.reserved2, 2708 &devmode.panningwidth, 2709 &devmode.panningheight, 2710 &devmode.nt_dev_private); 2711 2712 if (devmode.nt_dev_private) { 2713 /* the len in tdb_unpack is an int value and 2714 * devmode.driverextra is only a short 2715 */ 2716 len += tdb_unpack(buf+len, buflen-len, "B", &extra_len, &devmode.nt_dev_private); 2717 devmode.driverextra=(uint16)extra_len; 2718 2719 /* check to catch an invalid TDB entry so we don't segfault */ 2720 if (devmode.driverextra == 0) { 2721 devmode.nt_dev_private = NULL; 2722 } 2723 } 2724 2725 *nt_devmode = (NT_DEVICEMODE *)memdup(&devmode, sizeof(devmode)); 2726 if (!*nt_devmode) { 2727 SAFE_FREE(devmode.nt_dev_private); 2728 return -1; 2729 } 2730 2731 DEBUG(8,("Unpacked devicemode [%s](%s)\n", devmode.devicename, devmode.formname)); 2732 if (devmode.nt_dev_private) 2733 DEBUG(8,("with a private section of %d bytes\n", devmode.driverextra)); 2734 2735 return len; 2736 } 2737 2738 /**************************************************************************** 2739 Allocate and initialize a new slot. 2740 ***************************************************************************/ 2741 2742 int add_new_printer_key( NT_PRINTER_DATA *data, const char *name ) 2743 { 2744 NT_PRINTER_KEY *d; 2745 int key_index; 2746 2747 if ( !name || !data ) 2748 return -1; 2749 2750 /* allocate another slot in the NT_PRINTER_KEY array */ 2751 2752 if ( !(d = TALLOC_REALLOC_ARRAY( data, data->keys, NT_PRINTER_KEY, data->num_keys+1)) ) { 2753 DEBUG(0,("add_new_printer_key: Realloc() failed!\n")); 2754 return -1; 2755 } 2756 2757 data->keys = d; 2758 2759 key_index = data->num_keys; 2760 2761 /* initialze new key */ 2762 2763 data->keys[key_index].name = talloc_strdup( data, name ); 2764 2765 if ( !(data->keys[key_index].values = TALLOC_ZERO_P( data, struct regval_ctr )) ) 2766 return -1; 2767 2768 data->num_keys++; 2769 2770 DEBUG(10,("add_new_printer_key: Inserted new data key [%s]\n", name )); 2771 2772 return key_index; 2773 } 2774 2775 /**************************************************************************** 2776 search for a registry key name in the existing printer data 2777 ***************************************************************************/ 2778 2779 int delete_printer_key( NT_PRINTER_DATA *data, const char *name ) 2780 { 2781 int i; 2782 2783 for ( i=0; i<data->num_keys; i++ ) { 2784 if ( strequal( data->keys[i].name, name ) ) { 2785 2786 /* cleanup memory */ 2787 2788 TALLOC_FREE( data->keys[i].name ); 2789 TALLOC_FREE( data->keys[i].values ); 2790 2791 /* if not the end of the array, move remaining elements down one slot */ 2792 2793 data->num_keys--; 2794 if ( data->num_keys && (i < data->num_keys) ) 2795 memmove( &data->keys[i], &data->keys[i+1], sizeof(NT_PRINTER_KEY)*(data->num_keys-i) ); 2796 2797 break; 2798 } 2799 } 2800 2801 2802 return data->num_keys; 2803 } 2804 2805 /**************************************************************************** 2806 search for a registry key name in the existing printer data 2807 ***************************************************************************/ 2808 2809 int lookup_printerkey( NT_PRINTER_DATA *data, const char *name ) 2810 { 2811 int key_index = -1; 2812 int i; 2813 2814 if ( !data || !name ) 2815 return -1; 2816 2817 DEBUG(12,("lookup_printerkey: Looking for [%s]\n", name)); 2818 2819 /* loop over all existing keys */ 2820 2821 for ( i=0; i<data->num_keys; i++ ) { 2822 if ( strequal(data->keys[i].name, name) ) { 2823 DEBUG(12,("lookup_printerkey: Found [%s]!\n", name)); 2824 key_index = i; 2825 break; 2826 2827 } 2828 } 2829 2830 return key_index; 2831 } 2832 2833 /**************************************************************************** 2834 ***************************************************************************/ 2835 2836 int get_printer_subkeys( NT_PRINTER_DATA *data, const char* key, fstring **subkeys ) 2837 { 2838 int i, j; 2839 int key_len; 2840 int num_subkeys = 0; 2841 char *p; 2842 fstring *subkeys_ptr = NULL; 2843 fstring subkeyname; 2844 2845 *subkeys = NULL; 2846 2847 if ( !data ) 2848 return 0; 2849 2850 if ( !key ) 2851 return -1; 2852 2853 /* special case of asking for the top level printer data registry key names */ 2854 2855 if ( strlen(key) == 0 ) { 2856 for ( i=0; i<data->num_keys; i++ ) { 2857 2858 /* found a match, so allocate space and copy the name */ 2859 2860 if ( !(subkeys_ptr = SMB_REALLOC_ARRAY( subkeys_ptr, fstring, num_subkeys+2)) ) { 2861 DEBUG(0,("get_printer_subkeys: Realloc failed for [%d] entries!\n", 2862 num_subkeys+1)); 2863 return -1; 2864 } 2865 2866 fstrcpy( subkeys_ptr[num_subkeys], data->keys[i].name ); 2867 num_subkeys++; 2868 } 2869 2870 goto done; 2871 } 2872 2873 /* asking for the subkeys of some key */ 2874 /* subkey paths are stored in the key name using '\' as the delimiter */ 2875 2876 for ( i=0; i<data->num_keys; i++ ) { 2877 if ( StrnCaseCmp(data->keys[i].name, key, strlen(key)) == 0 ) { 2878 2879 /* if we found the exact key, then break */ 2880 key_len = strlen( key ); 2881 if ( strlen(data->keys[i].name) == key_len ) 2882 break; 2883 2884 /* get subkey path */ 2885 2886 p = data->keys[i].name + key_len; 2887 if ( *p == '\\' ) 2888 p++; 2889 fstrcpy( subkeyname, p ); 2890 if ( (p = strchr( subkeyname, '\\' )) ) 2891 *p = '\0'; 2892 2893 /* don't add a key more than once */ 2894 2895 for ( j=0; j<num_subkeys; j++ ) { 2896 if ( strequal( subkeys_ptr[j], subkeyname ) ) 2897 break; 2898 } 2899 2900 if ( j != num_subkeys ) 2901 continue; 2902 2903 /* found a match, so allocate space and copy the name */ 2904 2905 if ( !(subkeys_ptr = SMB_REALLOC_ARRAY( subkeys_ptr, fstring, num_subkeys+2)) ) { 2906 DEBUG(0,("get_printer_subkeys: Realloc failed for [%d] entries!\n", 2907 num_subkeys+1)); 2908 return 0; 2909 } 2910 2911 fstrcpy( subkeys_ptr[num_subkeys], subkeyname ); 2912 num_subkeys++; 2913 } 2914 2915 } 2916 2917 /* return error if the key was not found */ 2918 2919 if ( i == data->num_keys ) { 2920 SAFE_FREE(subkeys_ptr); 2921 return -1; 2922 } 2923 2924 done: 2925 /* tag off the end */ 2926 2927 if (num_subkeys) 2928 fstrcpy(subkeys_ptr[num_subkeys], "" ); 2929 2930 *subkeys = subkeys_ptr; 2931 2932 return num_subkeys; 2933 } 2934 2935 #ifdef HAVE_ADS 2936 static void map_sz_into_ctr(struct regval_ctr *ctr, const char *val_name, 2937 const char *sz) 2938 { 2939 regval_ctr_delvalue(ctr, val_name); 2940 regval_ctr_addvalue_sz(ctr, val_name, sz); 2941 } 2942 2943 static void map_dword_into_ctr(struct regval_ctr *ctr, const char *val_name, 2944 uint32 dword) 2945 { 2946 regval_ctr_delvalue(ctr, val_name); 2947 regval_ctr_addvalue(ctr, val_name, REG_DWORD, 2948 (char *) &dword, sizeof(dword)); 2949 } 2950 2951 static void map_bool_into_ctr(struct regval_ctr *ctr, const char *val_name, 2952 bool b) 2953 { 2954 uint8 bin_bool = (b ? 1 : 0); 2955 regval_ctr_delvalue(ctr, val_name); 2956 regval_ctr_addvalue(ctr, val_name, REG_BINARY, 2957 (char *) &bin_bool, sizeof(bin_bool)); 2958 } 2959 2960 static void map_single_multi_sz_into_ctr(struct regval_ctr *ctr, const char *val_name, 2961 const char *multi_sz) 2962 { 2963 const char *a[2]; 2964 2965 a[0] = multi_sz; 2966 a[1] = NULL; 2967 2968 regval_ctr_delvalue(ctr, val_name); 2969 regval_ctr_addvalue_multi_sz(ctr, val_name, a); 2970 } 2971 2972 /**************************************************************************** 2973 * Map the NT_PRINTER_INFO_LEVEL_2 data into DsSpooler keys for publishing. 2974 * 2975 * @param info2 NT_PRINTER_INFO_LEVEL_2 describing printer - gets modified 2976 * @return bool indicating success or failure 2977 ***************************************************************************/ 2978 2979 static bool map_nt_printer_info2_to_dsspooler(NT_PRINTER_INFO_LEVEL_2 *info2) 2980 { 2981 struct regval_ctr *ctr = NULL; 2982 fstring longname; 2983 const char *dnssuffix; 2984 char *allocated_string = NULL; 2985 const char *ascii_str; 2986 int i; 2987 2988 if ((i = lookup_printerkey(info2->data, SPOOL_DSSPOOLER_KEY)) < 0) 2989 i = add_new_printer_key(info2->data, SPOOL_DSSPOOLER_KEY); 2990 ctr = info2->data->keys[i].values; 2991 2992 map_sz_into_ctr(ctr, SPOOL_REG_PRINTERNAME, info2->sharename); 2993 map_sz_into_ctr(ctr, SPOOL_REG_SHORTSERVERNAME, global_myname()); 2994 2995 /* we make the assumption that the netbios name is the same 2996 as the DNS name sinc ethe former will be what we used to 2997 join the domain */ 2998 2999 dnssuffix = get_mydnsdomname(talloc_tos()); 3000 if (dnssuffix && *dnssuffix) { 3001 fstr_sprintf( longname, "%s.%s", global_myname(), dnssuffix ); 3002 } else { 3003 fstrcpy( longname, global_myname() ); 3004 } 3005 3006 map_sz_into_ctr(ctr, SPOOL_REG_SERVERNAME, longname); 3007 3008 if (asprintf(&allocated_string, "\\\\%s\\%s", longname, info2->sharename) == -1) { 3009 return false; 3010 } 3011 map_sz_into_ctr(ctr, SPOOL_REG_UNCNAME, allocated_string); 3012 SAFE_FREE(allocated_string); 3013 3014 map_dword_into_ctr(ctr, SPOOL_REG_VERSIONNUMBER, 4); 3015 map_sz_into_ctr(ctr, SPOOL_REG_DRIVERNAME, info2->drivername); 3016 map_sz_into_ctr(ctr, SPOOL_REG_LOCATION, info2->location); 3017 map_sz_into_ctr(ctr, SPOOL_REG_DESCRIPTION, info2->comment); 3018 map_single_multi_sz_into_ctr(ctr, SPOOL_REG_PORTNAME, info2->portname); 3019 map_sz_into_ctr(ctr, SPOOL_REG_PRINTSEPARATORFILE, info2->sepfile); 3020 map_dword_into_ctr(ctr, SPOOL_REG_PRINTSTARTTIME, info2->starttime); 3021 map_dword_into_ctr(ctr, SPOOL_REG_PRINTENDTIME, info2->untiltime); 3022 map_dword_into_ctr(ctr, SPOOL_REG_PRIORITY, info2->priority); 3023 3024 map_bool_into_ctr(ctr, SPOOL_REG_PRINTKEEPPRINTEDJOBS, 3025 (info2->attributes & 3026 PRINTER_ATTRIBUTE_KEEPPRINTEDJOBS)); 3027 3028 switch (info2->attributes & 0x3) { 3029 case 0: 3030 ascii_str = SPOOL_REGVAL_PRINTWHILESPOOLING; 3031 break; 3032 case 1: 3033 ascii_str = SPOOL_REGVAL_PRINTAFTERSPOOLED; 3034 break; 3035 case 2: 3036 ascii_str = SPOOL_REGVAL_PRINTDIRECT; 3037 break; 3038 default: 3039 ascii_str = "unknown"; 3040 } 3041 map_sz_into_ctr(ctr, SPOOL_REG_PRINTSPOOLING, ascii_str); 3042 3043 return True; 3044 } 3045 3046 /***************************************************************** 3047 ****************************************************************/ 3048 3049 static void store_printer_guid(NT_PRINTER_INFO_LEVEL_2 *info2, 3050 struct GUID guid) 3051 { 3052 int i; 3053 struct regval_ctr *ctr=NULL; 3054 3055 /* find the DsSpooler key */ 3056 if ((i = lookup_printerkey(info2->data, SPOOL_DSSPOOLER_KEY)) < 0) 3057 i = add_new_printer_key(info2->data, SPOOL_DSSPOOLER_KEY); 3058 ctr = info2->data->keys[i].values; 3059 3060 regval_ctr_delvalue(ctr, "objectGUID"); 3061 3062 /* We used to store this as a REG_BINARY but that causes 3063 Vista to whine */ 3064 3065 regval_ctr_addvalue_sz(ctr, "objectGUID", 3066 GUID_string(talloc_tos(), &guid)); 3067 } 3068 3069 static WERROR nt_printer_publish_ads(ADS_STRUCT *ads, 3070 NT_PRINTER_INFO_LEVEL *printer) 3071 { 3072 ADS_STATUS ads_rc; 3073 LDAPMessage *res; 3074 char *prt_dn = NULL, *srv_dn, *srv_cn_0, *srv_cn_escaped, *sharename_escaped; 3075 char *srv_dn_utf8, **srv_cn_utf8; 3076 TALLOC_CTX *ctx; 3077 ADS_MODLIST mods; 3078 const char *attrs[] = {"objectGUID", NULL}; 3079 struct GUID guid; 3080 WERROR win_rc = WERR_OK; 3081 size_t converted_size; 3082 3083 /* build the ads mods */ 3084 ctx = talloc_init("nt_printer_publish_ads"); 3085 if (ctx == NULL) { 3086 return WERR_NOMEM; 3087 } 3088 3089 DEBUG(5, ("publishing printer %s\n", printer->info_2->printername)); 3090 3091 /* figure out where to publish */ 3092 ads_find_machine_acct(ads, &res, global_myname()); 3093 3094 /* We use ldap_get_dn here as we need the answer 3095 * in utf8 to call ldap_explode_dn(). JRA. */ 3096 3097 srv_dn_utf8 = ldap_get_dn((LDAP *)ads->ldap.ld, (LDAPMessage *)res); 3098 if (!srv_dn_utf8) { 3099 TALLOC_FREE(ctx); 3100 return WERR_SERVER_UNAVAILABLE; 3101 } 3102 ads_msgfree(ads, res); 3103 srv_cn_utf8 = ldap_explode_dn(srv_dn_utf8, 1); 3104 if (!srv_cn_utf8) { 3105 TALLOC_FREE(ctx); 3106 ldap_memfree(srv_dn_utf8); 3107 return WERR_SERVER_UNAVAILABLE; 3108 } 3109 /* Now convert to CH_UNIX. */ 3110 if (!pull_utf8_talloc(ctx, &srv_dn, srv_dn_utf8, &converted_size)) { 3111 TALLOC_FREE(ctx); 3112 ldap_memfree(srv_dn_utf8); 3113 ldap_memfree(srv_cn_utf8); 3114 return WERR_SERVER_UNAVAILABLE; 3115 } 3116 if (!pull_utf8_talloc(ctx, &srv_cn_0, srv_cn_utf8[0], &converted_size)) { 3117 TALLOC_FREE(ctx); 3118 ldap_memfree(srv_dn_utf8); 3119 ldap_memfree(srv_cn_utf8); 3120 TALLOC_FREE(srv_dn); 3121 return WERR_SERVER_UNAVAILABLE; 3122 } 3123 3124 ldap_memfree(srv_dn_utf8); 3125 ldap_memfree(srv_cn_utf8); 3126 3127 srv_cn_escaped = escape_rdn_val_string_alloc(srv_cn_0); 3128 if (!srv_cn_escaped) { 3129 TALLOC_FREE(ctx); 3130 return WERR_SERVER_UNAVAILABLE; 3131 } 3132 sharename_escaped = escape_rdn_val_string_alloc(printer->info_2->sharename); 3133 if (!sharename_escaped) { 3134 SAFE_FREE(srv_cn_escaped); 3135 TALLOC_FREE(ctx); 3136 return WERR_SERVER_UNAVAILABLE; 3137 } 3138 3139 prt_dn = talloc_asprintf(ctx, "cn=%s-%s,%s", srv_cn_escaped, sharename_escaped, srv_dn); 3140 3141 SAFE_FREE(srv_cn_escaped); 3142 SAFE_FREE(sharename_escaped); 3143 3144 mods = ads_init_mods(ctx); 3145 3146 if (mods == NULL) { 3147 SAFE_FREE(prt_dn); 3148 TALLOC_FREE(ctx); 3149 return WERR_NOMEM; 3150 } 3151 3152 get_local_printer_publishing_data(ctx, &mods, printer->info_2->data); 3153 ads_mod_str(ctx, &mods, SPOOL_REG_PRINTERNAME, 3154 printer->info_2->sharename); 3155 3156 /* publish it */ 3157 ads_rc = ads_mod_printer_entry(ads, prt_dn, ctx, &mods); 3158 if (ads_rc.err.rc == LDAP_NO_SUCH_OBJECT) { 3159 int i; 3160 for (i=0; mods[i] != 0; i++) 3161 ; 3162 mods[i] = (LDAPMod *)-1; 3163 ads_rc = ads_add_printer_entry(ads, prt_dn, ctx, &mods); 3164 } 3165 3166 if (!ADS_ERR_OK(ads_rc)) 3167 DEBUG(3, ("error publishing %s: %s\n", printer->info_2->sharename, ads_errstr(ads_rc))); 3168 3169 /* retreive the guid and store it locally */ 3170 if (ADS_ERR_OK(ads_search_dn(ads, &res, prt_dn, attrs))) { 3171 ZERO_STRUCT(guid); 3172 ads_pull_guid(ads, res, &guid); 3173 ads_msgfree(ads, res); 3174 store_printer_guid(printer->info_2, guid); 3175 win_rc = mod_a_printer(printer, 2); 3176 } 3177 TALLOC_FREE(ctx); 3178 3179 return win_rc; 3180 } 3181 3182 static WERROR nt_printer_unpublish_ads(ADS_STRUCT *ads, 3183 NT_PRINTER_INFO_LEVEL *printer) 3184 { 3185 ADS_STATUS ads_rc; 3186 LDAPMessage *res = NULL; 3187 char *prt_dn = NULL; 3188 3189 DEBUG(5, ("unpublishing printer %s\n", printer->info_2->printername)); 3190 3191 /* remove the printer from the directory */ 3192 ads_rc = ads_find_printer_on_server(ads, &res, 3193 printer->info_2->sharename, global_myname()); 3194 3195 if (ADS_ERR_OK(ads_rc) && res && ads_count_replies(ads, res)) { 3196 prt_dn = ads_get_dn(ads, talloc_tos(), res); 3197 if (!prt_dn) { 3198 ads_msgfree(ads, res); 3199 return WERR_NOMEM; 3200 } 3201 ads_rc = ads_del_dn(ads, prt_dn); 3202 TALLOC_FREE(prt_dn); 3203 } 3204 3205 if (res) { 3206 ads_msgfree(ads, res); 3207 } 3208 return WERR_OK; 3209 } 3210 3211 /**************************************************************************** 3212 * Publish a printer in the directory 3213 * 3214 * @param snum describing printer service 3215 * @return WERROR indicating status of publishing 3216 ***************************************************************************/ 3217 3218 WERROR nt_printer_publish(Printer_entry *print_hnd, int snum, int action) 3219 { 3220 ADS_STATUS ads_rc; 3221 ADS_STRUCT *ads = NULL; 3222 NT_PRINTER_INFO_LEVEL *printer = NULL; 3223 WERROR win_rc; 3224 3225 win_rc = get_a_printer(print_hnd, &printer, 2, lp_servicename(snum)); 3226 if (!W_ERROR_IS_OK(win_rc)) 3227 goto done; 3228 3229 switch (action) { 3230 case DSPRINT_PUBLISH: 3231 case DSPRINT_UPDATE: 3232 /* set the DsSpooler info and attributes */ 3233 if (!(map_nt_printer_info2_to_dsspooler(printer->info_2))) { 3234 win_rc = WERR_NOMEM; 3235 goto done; 3236 } 3237 3238 printer->info_2->attributes |= PRINTER_ATTRIBUTE_PUBLISHED; 3239 break; 3240 case DSPRINT_UNPUBLISH: 3241 printer->info_2->attributes ^= PRINTER_ATTRIBUTE_PUBLISHED; 3242 break; 3243 default: 3244 win_rc = WERR_NOT_SUPPORTED; 3245 goto done; 3246 } 3247 3248 win_rc = mod_a_printer(printer, 2); 3249 if (!W_ERROR_IS_OK(win_rc)) { 3250 DEBUG(3, ("err %d saving data\n", W_ERROR_V(win_rc))); 3251 goto done; 3252 } 3253 3254 ads = ads_init(lp_realm(), lp_workgroup(), NULL); 3255 if (!ads) { 3256 DEBUG(3, ("ads_init() failed\n")); 3257 win_rc = WERR_SERVER_UNAVAILABLE; 3258 goto done; 3259 } 3260 setenv(KRB5_ENV_CCNAME, "MEMORY:prtpub_cache", 1); 3261 SAFE_FREE(ads->auth.password); 3262 ads->auth.password = secrets_fetch_machine_password(lp_workgroup(), 3263 NULL, NULL); 3264 3265 /* ads_connect() will find the DC for us */ 3266 ads_rc = ads_connect(ads); 3267 if (!ADS_ERR_OK(ads_rc)) { 3268 DEBUG(3, ("ads_connect failed: %s\n", ads_errstr(ads_rc))); 3269 win_rc = WERR_ACCESS_DENIED; 3270 goto done; 3271 } 3272 3273 switch (action) { 3274 case DSPRINT_PUBLISH: 3275 case DSPRINT_UPDATE: 3276 win_rc = nt_printer_publish_ads(ads, printer); 3277 break; 3278 case DSPRINT_UNPUBLISH: 3279 win_rc = nt_printer_unpublish_ads(ads, printer); 3280 break; 3281 } 3282 3283 done: 3284 free_a_printer(&printer, 2); 3285 ads_destroy(&ads); 3286 return win_rc; 3287 } 3288 3289 WERROR check_published_printers(void) 3290 { 3291 ADS_STATUS ads_rc; 3292 ADS_STRUCT *ads = NULL; 3293 int snum; 3294 int n_services = lp_numservices(); 3295 NT_PRINTER_INFO_LEVEL *printer = NULL; 3296 3297 ads = ads_init(lp_realm(), lp_workgroup(), NULL); 3298 if (!ads) { 3299 DEBUG(3, ("ads_init() failed\n")); 3300 return WERR_SERVER_UNAVAILABLE; 3301 } 3302 setenv(KRB5_ENV_CCNAME, "MEMORY:prtpub_cache", 1); 3303 SAFE_FREE(ads->auth.password); 3304 ads->auth.password = secrets_fetch_machine_password(lp_workgroup(), 3305 NULL, NULL); 3306 3307 /* ads_connect() will find the DC for us */ 3308 ads_rc = ads_connect(ads); 3309 if (!ADS_ERR_OK(ads_rc)) { 3310 DEBUG(3, ("ads_connect failed: %s\n", ads_errstr(ads_rc))); 3311 ads_destroy(&ads); 3312 ads_kdestroy("MEMORY:prtpub_cache"); 3313 return WERR_ACCESS_DENIED; 3314 } 3315 3316 for (snum = 0; snum < n_services; snum++) { 3317 if (!(lp_snum_ok(snum) && lp_print_ok(snum))) 3318 continue; 3319 3320 if (W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, 3321 lp_servicename(snum))) && 3322 (printer->info_2->attributes & PRINTER_ATTRIBUTE_PUBLISHED)) 3323 nt_printer_publish_ads(ads, printer); 3324 3325 free_a_printer(&printer, 2); 3326 } 3327 3328 ads_destroy(&ads); 3329 ads_kdestroy("MEMORY:prtpub_cache"); 3330 return WERR_OK; 3331 } 3332 3333 bool is_printer_published(Printer_entry *print_hnd, int snum, 3334 struct GUID *guid) 3335 { 3336 NT_PRINTER_INFO_LEVEL *printer = NULL; 3337 struct regval_ctr *ctr; 3338 struct regval_blob *guid_val; 3339 WERROR win_rc; 3340 int i; 3341 bool ret = False; 3342 DATA_BLOB blob; 3343 3344 win_rc = get_a_printer(print_hnd, &printer, 2, lp_servicename(snum)); 3345 3346 if (!W_ERROR_IS_OK(win_rc) || 3347 !(printer->info_2->attributes & PRINTER_ATTRIBUTE_PUBLISHED) || 3348 ((i = lookup_printerkey(printer->info_2->data, SPOOL_DSSPOOLER_KEY)) < 0) || 3349 !(ctr = printer->info_2->data->keys[i].values) || 3350 !(guid_val = regval_ctr_getvalue(ctr, "objectGUID"))) 3351 { 3352 free_a_printer(&printer, 2); 3353 return False; 3354 } 3355 3356 /* fetching printer guids really ought to be a separate function. */ 3357 3358 if ( guid ) { 3359 char *guid_str; 3360 3361 /* We used to store the guid as REG_BINARY, then swapped 3362 to REG_SZ for Vista compatibility so check for both */ 3363 3364 switch ( regval_type(guid_val) ){ 3365 case REG_SZ: 3366 blob = data_blob_const(regval_data_p(guid_val), 3367 regval_size(guid_val)); 3368 pull_reg_sz(talloc_tos(), &blob, (const char **)&guid_str); 3369 ret = NT_STATUS_IS_OK(GUID_from_string( guid_str, guid )); 3370 talloc_free(guid_str); 3371 break; 3372 case REG_BINARY: 3373 if ( regval_size(guid_val) != sizeof(struct GUID) ) { 3374 ret = False; 3375 break; 3376 } 3377 memcpy(guid, regval_data_p(guid_val), sizeof(struct GUID)); 3378 break; 3379 default: 3380 DEBUG(0,("is_printer_published: GUID value stored as " 3381 "invaluid type (%d)\n", regval_type(guid_val) )); 3382 break; 3383 } 3384 } 3385 3386 free_a_printer(&printer, 2); 3387 return ret; 3388 } 3389 #else 3390 WERROR nt_printer_publish(Printer_entry *print_hnd, int snum, int action) 3391 { 3392 return WERR_OK; 3393 } 3394 3395 WERROR check_published_printers(void) 3396 { 3397 return WERR_OK; 3398 } 3399 3400 bool is_printer_published(Printer_entry *print_hnd, int snum, 3401 struct GUID *guid) 3402 { 3403 return False; 3404 } 3405 #endif /* HAVE_ADS */ 3406 3407 /**************************************************************************** 3408 ***************************************************************************/ 3409 3410 WERROR delete_all_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, const char *key ) 3411 { 3412 NT_PRINTER_DATA *data; 3413 int i; 3414 int removed_keys = 0; 3415 int empty_slot; 3416 3417 data = p2->data; 3418 empty_slot = data->num_keys; 3419 3420 if ( !key ) 3421 return WERR_INVALID_PARAM; 3422 3423 /* remove all keys */ 3424 3425 if ( !strlen(key) ) { 3426 3427 TALLOC_FREE( data ); 3428 3429 p2->data = NULL; 3430 3431 DEBUG(8,("delete_all_printer_data: Removed all Printer Data from printer [%s]\n", 3432 p2->printername )); 3433 3434 return WERR_OK; 3435 } 3436 3437 /* remove a specific key (and all subkeys) */ 3438 3439 for ( i=0; i<data->num_keys; i++ ) { 3440 if ( StrnCaseCmp( data->keys[i].name, key, strlen(key)) == 0 ) { 3441 DEBUG(8,("delete_all_printer_data: Removed all Printer Data from key [%s]\n", 3442 data->keys[i].name)); 3443 3444 TALLOC_FREE( data->keys[i].name ); 3445 TALLOC_FREE( data->keys[i].values ); 3446 3447 /* mark the slot as empty */ 3448 3449 ZERO_STRUCTP( &data->keys[i] ); 3450 } 3451 } 3452 3453 /* find the first empty slot */ 3454 3455 for ( i=0; i<data->num_keys; i++ ) { 3456 if ( !data->keys[i].name ) { 3457 empty_slot = i; 3458 removed_keys++; 3459 break; 3460 } 3461 } 3462 3463 if ( i == data->num_keys ) 3464 /* nothing was removed */ 3465 return WERR_INVALID_PARAM; 3466 3467 /* move everything down */ 3468 3469 for ( i=empty_slot+1; i<data->num_keys; i++ ) { 3470 if ( data->keys[i].name ) { 3471 memcpy( &data->keys[empty_slot], &data->keys[i], sizeof(NT_PRINTER_KEY) ); 3472 ZERO_STRUCTP( &data->keys[i] ); 3473 empty_slot++; 3474 removed_keys++; 3475 } 3476 } 3477 3478 /* update count */ 3479 3480 data->num_keys -= removed_keys; 3481 3482 /* sanity check to see if anything is left */ 3483 3484 if ( !data->num_keys ) { 3485 DEBUG(8,("delete_all_printer_data: No keys left for printer [%s]\n", p2->printername )); 3486 3487 SAFE_FREE( data->keys ); 3488 ZERO_STRUCTP( data ); 3489 } 3490 3491 return WERR_OK; 3492 } 3493 3494 /**************************************************************************** 3495 ***************************************************************************/ 3496 3497 WERROR delete_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, const char *key, const char *value ) 3498 { 3499 WERROR result = WERR_OK; 3500 int key_index; 3501 3502 /* we must have names on non-zero length */ 3503 3504 if ( !key || !*key|| !value || !*value ) 3505 return WERR_INVALID_NAME; 3506 3507 /* find the printer key first */ 3508 3509 key_index = lookup_printerkey( p2->data, key ); 3510 if ( key_index == -1 ) 3511 return WERR_OK; 3512 3513 /* make sure the value exists so we can return the correct error code */ 3514 3515 if ( !regval_ctr_getvalue( p2->data->keys[key_index].values, value ) ) 3516 return WERR_BADFILE; 3517 3518 regval_ctr_delvalue( p2->data->keys[key_index].values, value ); 3519 3520 DEBUG(8,("delete_printer_data: Removed key => [%s], value => [%s]\n", 3521 key, value )); 3522 3523 return result; 3524 } 3525 3526 /**************************************************************************** 3527 ***************************************************************************/ 3528 3529 WERROR add_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, const char *key, const char *value, 3530 uint32 type, uint8 *data, int real_len ) 3531 { 3532 WERROR result = WERR_OK; 3533 int key_index; 3534 3535 /* we must have names on non-zero length */ 3536 3537 if ( !key || !*key|| !value || !*value ) 3538 return WERR_INVALID_NAME; 3539 3540 /* find the printer key first */ 3541 3542 key_index = lookup_printerkey( p2->data, key ); 3543 if ( key_index == -1 ) 3544 key_index = add_new_printer_key( p2->data, key ); 3545 3546 if ( key_index == -1 ) 3547 return WERR_NOMEM; 3548 3549 regval_ctr_addvalue( p2->data->keys[key_index].values, value, 3550 type, (const char *)data, real_len ); 3551 3552 DEBUG(8,("add_printer_data: Added key => [%s], value => [%s], type=> [%d], size => [%d]\n", 3553 key, value, type, real_len )); 3554 3555 return result; 3556 } 3557 3558 /**************************************************************************** 3559 ***************************************************************************/ 3560 3561 struct regval_blob* get_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, const char *key, const char *value ) 3562 { 3563 int key_index; 3564 3565 if ( (key_index = lookup_printerkey( p2->data, key )) == -1 ) 3566 return NULL; 3567 3568 DEBUG(8,("get_printer_data: Attempting to lookup key => [%s], value => [%s]\n", 3569 key, value )); 3570 3571 return regval_ctr_getvalue( p2->data->keys[key_index].values, value ); 3572 } 3573 3574 /**************************************************************************** 3575 Unpack a list of registry values frem the TDB 3576 ***************************************************************************/ 3577 3578 static int unpack_values(NT_PRINTER_DATA *printer_data, const uint8 *buf, int buflen) 3579 { 3580 int len = 0; 3581 uint32 type; 3582 fstring string; 3583 const char *valuename = NULL; 3584 const char *keyname = NULL; 3585 char *str; 3586 int size; 3587 uint8 *data_p; 3588 struct regval_blob *regval_p; 3589 int key_index; 3590 3591 /* add the "PrinterDriverData" key first for performance reasons */ 3592 3593 add_new_printer_key( printer_data, SPOOL_PRINTERDATA_KEY ); 3594 3595 /* loop and unpack the rest of the registry values */ 3596 3597 while ( True ) { 3598 3599 /* check to see if there are any more registry values */ 3600 3601 regval_p = NULL; 3602 len += tdb_unpack(buf+len, buflen-len, "p", ®val_p); 3603 if ( !regval_p ) 3604 break; 3605 3606 /* unpack the next regval */ 3607 3608 len += tdb_unpack(buf+len, buflen-len, "fdB", 3609 string, 3610 &type, 3611 &size, 3612 &data_p); 3613 3614 /* lookup for subkey names which have a type of REG_NONE */ 3615 /* there's no data with this entry */ 3616 3617 if ( type == REG_NONE ) { 3618 if ( (key_index=lookup_printerkey( printer_data, string)) == -1 ) 3619 add_new_printer_key( printer_data, string ); 3620 continue; 3621 } 3622 3623 /* 3624 * break of the keyname from the value name. 3625 * Valuenames can have embedded '\'s so be careful. 3626 * only support one level of keys. See the 3627 * "Konica Fiery S300 50C-K v1.1. enu" 2k driver. 3628 * -- jerry 3629 */ 3630 3631 str = strchr_m( string, '\\'); 3632 3633 /* Put in "PrinterDriverData" is no key specified */ 3634 3635 if ( !str ) { 3636 keyname = SPOOL_PRINTERDATA_KEY; 3637 valuename = string; 3638 } 3639 else { 3640 *str = '\0'; 3641 keyname = string; 3642 valuename = str+1; 3643 } 3644 3645 /* see if we need a new key */ 3646 3647 if ( (key_index=lookup_printerkey( printer_data, keyname )) == -1 ) 3648 key_index = add_new_printer_key( printer_data, keyname ); 3649 3650 if ( key_index == -1 ) { 3651 DEBUG(0,("unpack_values: Failed to allocate a new key [%s]!\n", 3652 keyname)); 3653 break; 3654 } 3655 3656 DEBUG(8,("specific: [%s:%s], len: %d\n", keyname, valuename, size)); 3657 3658 /* Vista doesn't like unknown REG_BINARY values in DsSpooler. 3659 Thanks to Martin Zielinski for the hint. */ 3660 3661 if ( type == REG_BINARY && 3662 strequal( keyname, SPOOL_DSSPOOLER_KEY ) && 3663 strequal( valuename, "objectGUID" ) ) 3664 { 3665 struct GUID guid; 3666 3667 /* convert the GUID to a UNICODE string */ 3668 3669 memcpy( &guid, data_p, sizeof(struct GUID) ); 3670 3671 regval_ctr_addvalue_sz(printer_data->keys[key_index].values, 3672 valuename, 3673 GUID_string(talloc_tos(), &guid)); 3674 3675 } else { 3676 /* add the value */ 3677 3678 regval_ctr_addvalue( printer_data->keys[key_index].values, 3679 valuename, type, (const char *)data_p, 3680 size ); 3681 } 3682 3683 SAFE_FREE(data_p); /* 'B' option to tdbpack does a malloc() */ 3684 3685 } 3686 3687 return len; 3688 } 3689 3690 /**************************************************************************** 3691 ***************************************************************************/ 3692 3693 static char *last_from; 3694 static char *last_to; 3695 3696 static const char *get_last_from(void) 3697 { 3698 if (!last_from) { 3699 return ""; 3700 } 3701 return last_from; 3702 } 3703 3704 static const char *get_last_to(void) 3705 { 3706 if (!last_to) { 3707 return ""; 3708 } 3709 return last_to; 3710 } 3711 3712 static bool set_last_from_to(const char *from, const char *to) 3713 { 3714 char *orig_from = last_from; 3715 char *orig_to = last_to; 3716 3717 last_from = SMB_STRDUP(from); 3718 last_to = SMB_STRDUP(to); 3719 3720 SAFE_FREE(orig_from); 3721 SAFE_FREE(orig_to); 3722 3723 if (!last_from || !last_to) { 3724 SAFE_FREE(last_from); 3725 SAFE_FREE(last_to); 3726 return false; 3727 } 3728 return true; 3729 } 3730 3731 static void map_to_os2_driver(fstring drivername) 3732 { 3733 char *mapfile = lp_os2_driver_map(); 3734 char **lines = NULL; 3735 int numlines = 0; 3736 int i; 3737 3738 if (!strlen(drivername)) 3739 return; 3740 3741 if (!*mapfile) 3742 return; 3743 3744 if (strequal(drivername,get_last_from())) { 3745 DEBUG(3,("Mapped Windows driver %s to OS/2 driver %s\n", 3746 drivername,get_last_to())); 3747 fstrcpy(drivername,get_last_to()); 3748 return; 3749 } 3750 3751 lines = file_lines_load(mapfile, &numlines,0,NULL); 3752 if (numlines == 0 || lines == NULL) { 3753 DEBUG(0,("No entries in OS/2 driver map %s\n",mapfile)); 3754 TALLOC_FREE(lines); 3755 return; 3756 } 3757 3758 DEBUG(4,("Scanning OS/2 driver map %s\n",mapfile)); 3759 3760 for( i = 0; i < numlines; i++) { 3761 char *nt_name = lines[i]; 3762 char *os2_name = strchr(nt_name,'='); 3763 3764 if (!os2_name) 3765 continue; 3766 3767 *os2_name++ = 0; 3768 3769 while (isspace(*nt_name)) 3770 nt_name++; 3771 3772 if (!*nt_name || strchr("#;",*nt_name)) 3773 continue; 3774 3775 { 3776 int l = strlen(nt_name); 3777 while (l && isspace(nt_name[l-1])) { 3778 nt_name[l-1] = 0; 3779 l--; 3780 } 3781 } 3782 3783 while (isspace(*os2_name)) 3784 os2_name++; 3785 3786 { 3787 int l = strlen(os2_name); 3788 while (l && isspace(os2_name[l-1])) { 3789 os2_name[l-1] = 0; 3790 l--; 3791 } 3792 } 3793 3794 if (strequal(nt_name,drivername)) { 3795 DEBUG(3,("Mapped windows driver %s to os2 driver%s\n",drivername,os2_name)); 3796 set_last_from_to(drivername,os2_name); 3797 fstrcpy(drivername,os2_name); 3798 TALLOC_FREE(lines); 3799 return; 3800 } 3801 } 3802 3803 TALLOC_FREE(lines); 3804 } 3805 3806 /**************************************************************************** 3807 Get a default printer info 2 struct. 3808 ****************************************************************************/ 3809 3810 static WERROR get_a_printer_2_default(NT_PRINTER_INFO_LEVEL_2 *info, 3811 const char *servername, 3812 const char* sharename, 3813 bool get_loc_com) 3814 { 3815 int snum = lp_servicenumber(sharename); 3816 3817 slprintf(info->servername, sizeof(info->servername)-1, "\\\\%s", servername); 3818 slprintf(info->printername, sizeof(info->printername)-1, "\\\\%s\\%s", 3819 servername, sharename); 3820 fstrcpy(info->sharename, sharename); 3821 fstrcpy(info->portname, SAMBA_PRINTER_PORT_NAME); 3822 3823 /* by setting the driver name to an empty string, a local NT admin 3824 can now run the **local** APW to install a local printer driver 3825 for a Samba shared printer in 2.2. Without this, drivers **must** be 3826 installed on the Samba server for NT clients --jerry */ 3827 #if 0 /* JERRY --do not uncomment-- */ 3828 if (!*info->drivername) 3829 fstrcpy(info->drivername, "NO DRIVER AVAILABLE FOR THIS PRINTER"); 3830 #endif 3831 3832 3833 DEBUG(10,("get_a_printer_2_default: driver name set to [%s]\n", info->drivername)); 3834 3835 strlcpy(info->comment, "", sizeof(info->comment)); 3836 fstrcpy(info->printprocessor, "winprint"); 3837 fstrcpy(info->datatype, "RAW"); 3838 3839 #ifdef HAVE_CUPS 3840 if (get_loc_com && (enum printing_types)lp_printing(snum) == PRINT_CUPS ) { 3841 /* Pull the location and comment strings from cups if we don't 3842 already have one */ 3843 if ( !strlen(info->location) || !strlen(info->comment) ) 3844 cups_pull_comment_location( info ); 3845 } 3846 #endif 3847 3848 info->attributes = PRINTER_ATTRIBUTE_SAMBA; 3849 3850 info->starttime = 0; /* Minutes since 12:00am GMT */ 3851 info->untiltime = 0; /* Minutes since 12:00am GMT */ 3852 info->priority = 1; 3853 info->default_priority = 1; 3854 info->setuptime = (uint32)time(NULL); 3855 3856 /* 3857 * I changed this as I think it is better to have a generic 3858 * DEVMODE than to crash Win2k explorer.exe --jerry 3859 * See the HP Deskjet 990c Win2k drivers for an example. 3860 * 3861 * However the default devmode appears to cause problems 3862 * with the HP CLJ 8500 PCL driver. Hence the addition of 3863 * the "default devmode" parameter --jerry 22/01/2002 3864 */ 3865 3866 if (lp_default_devmode(snum)) { 3867 if ((info->devmode = construct_nt_devicemode(info->printername)) == NULL) { 3868 goto fail; 3869 } 3870 } else { 3871 info->devmode = NULL; 3872 } 3873 3874 if (!nt_printing_getsec(info, sharename, &info->secdesc_buf)) { 3875 goto fail; 3876 } 3877 3878 info->data = TALLOC_ZERO_P(info, NT_PRINTER_DATA); 3879 if (!info->data) { 3880 goto fail; 3881 } 3882 3883 add_new_printer_key(info->data, SPOOL_PRINTERDATA_KEY); 3884 3885 return WERR_OK; 3886 3887 fail: 3888 if (info->devmode) 3889 free_nt_devicemode(&info->devmode); 3890 3891 return WERR_ACCESS_DENIED; 3892 } 3893 3894 /**************************************************************************** 3895 ****************************************************************************/ 3896 3897 static WERROR get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info, 3898 const char *servername, 3899 const char *sharename, 3900 bool get_loc_com) 3901 { 3902 int len = 0; 3903 int snum = lp_servicenumber(sharename); 3904 TDB_DATA kbuf, dbuf; 3905 fstring printername; 3906 char adevice[MAXDEVICENAME]; 3907 char *comment = NULL; 3908 3909 kbuf = make_printer_tdbkey(talloc_tos(), sharename); 3910 3911 dbuf = tdb_fetch(tdb_printers, kbuf); 3912 if (!dbuf.dptr) { 3913 return get_a_printer_2_default(info, servername, 3914 sharename, get_loc_com); 3915 } 3916 3917 len += tdb_unpack(dbuf.dptr+len, dbuf.dsize-len, "dddddddddddfffffPfffff", 3918 &info->attributes, 3919 &info->priority, 3920 &info->default_priority, 3921 &info->starttime, 3922 &info->untiltime, 3923 &info->status, 3924 &info->cjobs, 3925 &info->averageppm, 3926 &info->changeid, 3927 &info->c_setprinter, 3928 &info->setuptime, 3929 info->servername, 3930 info->printername, 3931 info->sharename, 3932 info->portname, 3933 info->drivername, 3934 &comment, 3935 info->location, 3936 info->sepfile, 3937 info->printprocessor, 3938 info->datatype, 3939 info->parameters); 3940 3941 if (comment) { 3942 strlcpy(info->comment, comment, sizeof(info->comment)); 3943 SAFE_FREE(comment); 3944 } 3945 3946 /* Samba has to have shared raw drivers. */ 3947 info->attributes |= PRINTER_ATTRIBUTE_SAMBA; 3948 info->attributes &= ~PRINTER_ATTRIBUTE_NOT_SAMBA; 3949 3950 /* Restore the stripped strings. */ 3951 slprintf(info->servername, sizeof(info->servername)-1, "\\\\%s", servername); 3952 3953 if ( lp_force_printername(snum) ) { 3954 slprintf(printername, sizeof(printername)-1, "\\\\%s\\%s", servername, sharename ); 3955 } else { 3956 slprintf(printername, sizeof(printername)-1, "\\\\%s\\%s", servername, info->printername); 3957 } 3958 3959 fstrcpy(info->printername, printername); 3960 3961 #ifdef HAVE_CUPS 3962 if (get_loc_com && (enum printing_types)lp_printing(snum) == PRINT_CUPS ) { 3963 /* Pull the location and comment strings from cups if we don't 3964 already have one */ 3965 if ( !strlen(info->location) || !strlen(info->comment) ) 3966 cups_pull_comment_location( info ); 3967 } 3968 #endif 3969 3970 len += unpack_devicemode(&info->devmode,dbuf.dptr+len, dbuf.dsize-len); 3971 3972 /* 3973 * Some client drivers freak out if there is a NULL devmode 3974 * (probably the driver is not checking before accessing 3975 * the devmode pointer) --jerry 3976 * 3977 * See comments in get_a_printer_2_default() 3978 */ 3979 3980 if (lp_default_devmode(snum) && !info->devmode) { 3981 DEBUG(8,("get_a_printer_2: Constructing a default device mode for [%s]\n", 3982 printername)); 3983 info->devmode = construct_nt_devicemode(printername); 3984 } 3985 3986 slprintf( adevice, sizeof(adevice), "%s", info->printername ); 3987 if (info->devmode) { 3988 fstrcpy(info->devmode->devicename, adevice); 3989 } 3990 3991 if ( !(info->data = TALLOC_ZERO_P( info, NT_PRINTER_DATA )) ) { 3992 DEBUG(0,("unpack_values: talloc() failed!\n")); 3993 SAFE_FREE(dbuf.dptr); 3994 return WERR_NOMEM; 3995 } 3996 len += unpack_values( info->data, dbuf.dptr+len, dbuf.dsize-len ); 3997 3998 /* This will get the current RPC talloc context, but we should be 3999 passing this as a parameter... fixme... JRA ! */ 4000 4001 if (!nt_printing_getsec(info, sharename, &info->secdesc_buf)) { 4002 SAFE_FREE(dbuf.dptr); 4003 return WERR_NOMEM; 4004 } 4005 4006 /* Fix for OS/2 drivers. */ 4007 4008 if (get_remote_arch() == RA_OS2) { 4009 map_to_os2_driver(info->drivername); 4010 } 4011 4012 SAFE_FREE(dbuf.dptr); 4013 4014 DEBUG(9,("Unpacked printer [%s] name [%s] running driver [%s]\n", 4015 sharename, info->printername, info->drivername)); 4016 4017 return WERR_OK; 4018 } 4019 4020 /**************************************************************************** 4021 Debugging function, dump at level 6 the struct in the logs. 4022 ****************************************************************************/ 4023 static uint32 dump_a_printer(NT_PRINTER_INFO_LEVEL *printer, uint32 level) 4024 { 4025 uint32 result; 4026 NT_PRINTER_INFO_LEVEL_2 *info2; 4027 4028 DEBUG(106,("Dumping printer at level [%d]\n", level)); 4029 4030 switch (level) { 4031 case 2: 4032 { 4033 if (printer->info_2 == NULL) 4034 result=5; 4035 else 4036 { 4037 info2=printer->info_2; 4038 4039 DEBUGADD(106,("attributes:[%d]\n", info2->attributes)); 4040 DEBUGADD(106,("priority:[%d]\n", info2->priority)); 4041 DEBUGADD(106,("default_priority:[%d]\n", info2->default_priority)); 4042 DEBUGADD(106,("starttime:[%d]\n", info2->starttime)); 4043 DEBUGADD(106,("untiltime:[%d]\n", info2->untiltime)); 4044 DEBUGADD(106,("status:[%d]\n", info2->status)); 4045 DEBUGADD(106,("cjobs:[%d]\n", info2->cjobs)); 4046 DEBUGADD(106,("averageppm:[%d]\n", info2->averageppm)); 4047 DEBUGADD(106,("changeid:[%d]\n", info2->changeid)); 4048 DEBUGADD(106,("c_setprinter:[%d]\n", info2->c_setprinter)); 4049 DEBUGADD(106,("setuptime:[%d]\n", info2->setuptime)); 4050 4051 DEBUGADD(106,("servername:[%s]\n", info2->servername)); 4052 DEBUGADD(106,("printername:[%s]\n", info2->printername)); 4053 DEBUGADD(106,("sharename:[%s]\n", info2->sharename)); 4054 DEBUGADD(106,("portname:[%s]\n", info2->portname)); 4055 DEBUGADD(106,("drivername:[%s]\n", info2->drivername)); 4056 DEBUGADD(106,("comment:[%s]\n", info2->comment)); 4057 DEBUGADD(106,("location:[%s]\n", info2->location)); 4058 DEBUGADD(106,("sepfile:[%s]\n", info2->sepfile)); 4059 DEBUGADD(106,("printprocessor:[%s]\n", info2->printprocessor)); 4060 DEBUGADD(106,("datatype:[%s]\n", info2->datatype)); 4061 DEBUGADD(106,("parameters:[%s]\n", info2->parameters)); 4062 result=0; 4063 } 4064 break; 4065 } 4066 default: 4067 DEBUGADD(106,("dump_a_printer: Level %u not implemented\n", (unsigned int)level )); 4068 result=1; 4069 break; 4070 } 4071 4072 return result; 4073 } 4074 4075 /**************************************************************************** 4076 Update the changeid time. 4077 This is SO NASTY as some drivers need this to change, others need it 4078 static. This value will change every second, and I must hope that this 4079 is enough..... DON'T CHANGE THIS CODE WITHOUT A TEST MATRIX THE SIZE OF 4080 UTAH ! JRA. 4081 ****************************************************************************/ 4082 4083 static uint32 rev_changeid(void) 4084 { 4085 struct timeval tv; 4086 4087 get_process_uptime(&tv); 4088 4089 #if 1 /* JERRY */ 4090 /* Return changeid as msec since spooler restart */ 4091 return tv.tv_sec * 1000 + tv.tv_usec / 1000; 4092 #else 4093 /* 4094 * This setting seems to work well but is too untested 4095 * to replace the above calculation. Left in for experiementation 4096 * of the reader --jerry (Tue Mar 12 09:15:05 CST 2002) 4097 */ 4098 return tv.tv_sec * 10 + tv.tv_usec / 100000; 4099 #endif 4100 } 4101 4102 4103 /* 4104 * The function below are the high level ones. 4105 * only those ones must be called from the spoolss code. 4106 * JFM. 4107 */ 4108 4109 /**************************************************************************** 4110 Modify a printer. This is called from SETPRINTERDATA/DELETEPRINTERDATA. 4111 ****************************************************************************/ 4112 4113 WERROR mod_a_printer(NT_PRINTER_INFO_LEVEL *printer, uint32 level) 4114 { 4115 WERROR result; 4116 4117 dump_a_printer(printer, level); 4118 4119 switch (level) { 4120 case 2: 4121 { 4122 /* 4123 * Update the changestamp. Emperical tests show that the 4124 * ChangeID is always updated,but c_setprinter is 4125 * global spooler variable (not per printer). 4126 */ 4127 4128 /* ChangeID **must** be increasing over the lifetime 4129 of client's spoolss service in order for the 4130 client's cache to show updates */ 4131 4132 printer->info_2->changeid = rev_changeid(); 4133 4134 /* 4135 * Because one day someone will ask: 4136 * NT->NT An admin connection to a remote 4137 * printer show changes imeediately in 4138 * the properities dialog 4139 * 4140 * A non-admin connection will only show the 4141 * changes after viewing the properites page 4142 * 2 times. Seems to be related to a 4143 * race condition in the client between the spooler 4144 * updating the local cache and the Explorer.exe GUI 4145 * actually displaying the properties. 4146 * 4147 * This is fixed in Win2k. admin/non-admin 4148 * connections both display changes immediately. 4149 * 4150 * 14/12/01 --jerry 4151 */ 4152 4153 result=update_a_printer_2(printer->info_2); 4154 break; 4155 } 4156 default: 4157 result=WERR_UNKNOWN_LEVEL; 4158 break; 4159 } 4160 4161 return result; 4162 } 4163 4164 /**************************************************************************** 4165 Initialize printer devmode & data with previously saved driver init values. 4166 ****************************************************************************/ 4167 4168 static bool set_driver_init_2( NT_PRINTER_INFO_LEVEL_2 *info_ptr ) 4169 { 4170 int len = 0; 4171 char *key = NULL; 4172 TDB_DATA dbuf; 4173 NT_PRINTER_INFO_LEVEL_2 info; 4174 4175 4176 ZERO_STRUCT(info); 4177 4178 /* 4179 * Delete any printer data 'values' already set. When called for driver 4180 * replace, there will generally be some, but during an add printer, there 4181 * should not be any (if there are delete them). 4182 */ 4183 4184 if ( info_ptr->data ) 4185 delete_all_printer_data( info_ptr, "" ); 4186 4187 if (asprintf(&key, "%s%s", DRIVER_INIT_PREFIX, 4188 info_ptr->drivername) < 0) { 4189 return false; 4190 } 4191 4192 dbuf = tdb_fetch_bystring(tdb_drivers, key); 4193 if (!dbuf.dptr) { 4194 /* 4195 * When changing to a driver that has no init info in the tdb, remove 4196 * the previous drivers init info and leave the new on blank. 4197 */ 4198 free_nt_devicemode(&info_ptr->devmode); 4199 SAFE_FREE(key); 4200 return false; 4201 } 4202 4203 SAFE_FREE(key); 4204 /* 4205 * Get the saved DEVMODE.. 4206 */ 4207 4208 len += unpack_devicemode(&info.devmode,dbuf.dptr+len, dbuf.dsize-len); 4209 4210 /* 4211 * The saved DEVMODE contains the devicename from the printer used during 4212 * the initialization save. Change it to reflect the new printer. 4213 */ 4214 4215 if ( info.devmode ) { 4216 ZERO_STRUCT(info.devmode->devicename); 4217 fstrcpy(info.devmode->devicename, info_ptr->printername); 4218 } 4219 4220 /* 4221 * NT/2k does not change out the entire DeviceMode of a printer 4222 * when changing the driver. Only the driverextra, private, & 4223 * driverversion fields. --jerry (Thu Mar 14 08:58:43 CST 2002) 4224 * 4225 * Later examination revealed that Windows NT/2k does reset the 4226 * the printer's device mode, bit **only** when you change a 4227 * property of the device mode such as the page orientation. 4228 * --jerry 4229 */ 4230 4231 4232 /* Bind the saved DEVMODE to the new the printer */ 4233 4234 free_nt_devicemode(&info_ptr->devmode); 4235 info_ptr->devmode = info.devmode; 4236 4237 DEBUG(10,("set_driver_init_2: Set printer [%s] init %s DEVMODE for driver [%s]\n", 4238 info_ptr->printername, info_ptr->devmode?"VALID":"NULL", info_ptr->drivername)); 4239 4240 /* Add the printer data 'values' to the new printer */ 4241 4242 if ( !(info_ptr->data = TALLOC_ZERO_P( info_ptr, NT_PRINTER_DATA )) ) { 4243 DEBUG(0,("set_driver_init_2: talloc() failed!\n")); 4244 return False; 4245 } 4246 4247 len += unpack_values( info_ptr->data, dbuf.dptr+len, dbuf.dsize-len ); 4248 4249 SAFE_FREE(dbuf.dptr); 4250 4251 return true; 4252 } 4253 4254 /**************************************************************************** 4255 Initialize printer devmode & data with previously saved driver init values. 4256 When a printer is created using AddPrinter, the drivername bound to the 4257 printer is used to lookup previously saved driver initialization info, which 4258 is bound to the new printer. 4259 ****************************************************************************/ 4260 4261 bool set_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level) 4262 { 4263 bool result = False; 4264 4265 switch (level) { 4266 case 2: 4267 result = set_driver_init_2(printer->info_2); 4268 break; 4269 4270 default: 4271 DEBUG(0,("set_driver_init: Programmer's error! Unknown driver_init level [%d]\n", 4272 level)); 4273 break; 4274 } 4275 4276 return result; 4277 } 4278 4279 /**************************************************************************** 4280 Delete driver init data stored for a specified driver 4281 ****************************************************************************/ 4282 4283 bool del_driver_init(const char *drivername) 4284 { 4285 char *key; 4286 bool ret; 4287 4288 if (!drivername || !*drivername) { 4289 DEBUG(3,("del_driver_init: No drivername specified!\n")); 4290 return false; 4291 } 4292 4293 if (asprintf(&key, "%s%s", DRIVER_INIT_PREFIX, drivername) < 0) { 4294 return false; 4295 } 4296 4297 DEBUG(6,("del_driver_init: Removing driver init data for [%s]\n", 4298 drivername)); 4299 4300 ret = (tdb_delete_bystring(tdb_drivers, key) == 0); 4301 SAFE_FREE(key); 4302 return ret; 4303 } 4304 4305 /**************************************************************************** 4306 Pack up the DEVMODE and values for a printer into a 'driver init' entry 4307 in the tdb. Note: this is different from the driver entry and the printer 4308 entry. There should be a single driver init entry for each driver regardless 4309 of whether it was installed from NT or 2K. Technically, they should be 4310 different, but they work out to the same struct. 4311 ****************************************************************************/ 4312 4313 static uint32 update_driver_init_2(NT_PRINTER_INFO_LEVEL_2 *info) 4314 { 4315 char *key = NULL; 4316 uint8 *buf; 4317 int buflen, len, ret; 4318 int retlen; 4319 TDB_DATA dbuf; 4320 4321 buf = NULL; 4322 buflen = 0; 4323 4324 again: 4325 len = 0; 4326 len += pack_devicemode(info->devmode, buf+len, buflen-len); 4327 4328 retlen = pack_values( info->data, buf+len, buflen-len ); 4329 if (retlen == -1) { 4330 ret = -1; 4331 goto done; 4332 } 4333 len += retlen; 4334 4335 if (buflen < len) { 4336 buf = (uint8 *)SMB_REALLOC(buf, len); 4337 if (!buf) { 4338 DEBUG(0, ("update_driver_init_2: failed to enlarge buffer!\n")); 4339 ret = -1; 4340 goto done; 4341 } 4342 buflen = len; 4343 goto again; 4344 } 4345 4346 SAFE_FREE(key); 4347 if (asprintf(&key, "%s%s", DRIVER_INIT_PREFIX, info->drivername) < 0) { 4348 ret = (uint32)-1; 4349 goto done; 4350 } 4351 4352 dbuf.dptr = buf; 4353 dbuf.dsize = len; 4354 4355 ret = tdb_store_bystring(tdb_drivers, key, dbuf, TDB_REPLACE); 4356 4357 done: 4358 if (ret == -1) 4359 DEBUG(8, ("update_driver_init_2: error updating printer init to tdb on disk\n")); 4360 4361 SAFE_FREE(buf); 4362 4363 DEBUG(10,("update_driver_init_2: Saved printer [%s] init DEVMODE & values for driver [%s]\n", 4364 info->sharename, info->drivername)); 4365 4366 return ret; 4367 } 4368 4369 /**************************************************************************** 4370 Update (i.e. save) the driver init info (DEVMODE and values) for a printer 4371 ****************************************************************************/ 4372 4373 static uint32 update_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level) 4374 { 4375 uint32 result; 4376 4377 dump_a_printer(printer, level); 4378 4379 switch (level) { 4380 case 2: 4381 result = update_driver_init_2(printer->info_2); 4382 break; 4383 default: 4384 result = 1; 4385 break; 4386 } 4387 4388 return result; 4389 } 4390 4391 /**************************************************************************** 4392 Convert the printer data value, a REG_BINARY array, into an initialization 4393 DEVMODE. Note: the array must be parsed as if it was a DEVMODE in an rpc... 4394 got to keep the endians happy :). 4395 ****************************************************************************/ 4396 4397 static bool convert_driver_init(TALLOC_CTX *mem_ctx, NT_DEVICEMODE *nt_devmode, 4398 const uint8_t *data, uint32_t data_len) 4399 { 4400 struct spoolss_DeviceMode devmode; 4401 enum ndr_err_code ndr_err; 4402 DATA_BLOB blob; 4403 4404 ZERO_STRUCT(devmode); 4405 4406 blob = data_blob_const(data, data_len); 4407 4408 ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, NULL, &devmode, 4409 (ndr_pull_flags_fn_t)ndr_pull_spoolss_DeviceMode); 4410 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 4411 DEBUG(10,("convert_driver_init: error parsing spoolss_DeviceMode\n")); 4412 return false; 4413 } 4414 4415 return convert_devicemode("", &devmode, &nt_devmode); 4416 } 4417 4418 /**************************************************************************** 4419 Set the DRIVER_INIT info in the tdb. Requires Win32 client code that: 4420 4421 1. Use the driver's config DLL to this UNC printername and: 4422 a. Call DrvPrintEvent with PRINTER_EVENT_INITIALIZE 4423 b. Call DrvConvertDevMode with CDM_DRIVER_DEFAULT to get default DEVMODE 4424 2. Call SetPrinterData with the 'magic' key and the DEVMODE as data. 4425 4426 The last step triggers saving the "driver initialization" information for 4427 this printer into the tdb. Later, new printers that use this driver will 4428 have this initialization information bound to them. This simulates the 4429 driver initialization, as if it had run on the Samba server (as it would 4430 have done on NT). 4431 4432 The Win32 client side code requirement sucks! But until we can run arbitrary 4433 Win32 printer driver code on any Unix that Samba runs on, we are stuck with it. 4434 4435 It would have been easier to use SetPrinter because all the UNMARSHALLING of 4436 the DEVMODE is done there, but 2K/XP clients do not set the DEVMODE... think 4437 about it and you will realize why. JRR 010720 4438 ****************************************************************************/ 4439 4440 static WERROR save_driver_init_2(NT_PRINTER_INFO_LEVEL *printer, uint8 *data, uint32 data_len ) 4441 { 4442 WERROR status = WERR_OK; 4443 TALLOC_CTX *ctx = NULL; 4444 NT_DEVICEMODE *nt_devmode = NULL; 4445 NT_DEVICEMODE *tmp_devmode = printer->info_2->devmode; 4446 4447 /* 4448 * When the DEVMODE is already set on the printer, don't try to unpack it. 4449 */ 4450 DEBUG(8,("save_driver_init_2: Enter...\n")); 4451 4452 if ( !printer->info_2->devmode && data_len ) { 4453 /* 4454 * Set devmode on printer info, so entire printer initialization can be 4455 * saved to tdb. 4456 */ 4457 4458 if ((ctx = talloc_init("save_driver_init_2")) == NULL) 4459 return WERR_NOMEM; 4460 4461 if ((nt_devmode = SMB_MALLOC_P(NT_DEVICEMODE)) == NULL) { 4462 status = WERR_NOMEM; 4463 goto done; 4464 } 4465 4466 ZERO_STRUCTP(nt_devmode); 4467 4468 /* 4469 * The DEVMODE is held in the 'data' component of the param in raw binary. 4470 * Convert it to to a devmode structure 4471 */ 4472 if ( !convert_driver_init( ctx, nt_devmode, data, data_len )) { 4473 DEBUG(10,("save_driver_init_2: error converting DEVMODE\n")); 4474 status = WERR_INVALID_PARAM; 4475 goto done; 4476 } 4477 4478 printer->info_2->devmode = nt_devmode; 4479 } 4480 4481 /* 4482 * Pack up and add (or update) the DEVMODE and any current printer data to 4483 * a 'driver init' element in the tdb 4484 * 4485 */ 4486 4487 if ( update_driver_init(printer, 2) != 0 ) { 4488 DEBUG(10,("save_driver_init_2: error updating DEVMODE\n")); 4489 status = WERR_NOMEM; 4490 goto done; 4491 } 4492 4493 /* 4494 * If driver initialization info was successfully saved, set the current 4495 * printer to match it. This allows initialization of the current printer 4496 * as well as the driver. 4497 */ 4498 status = mod_a_printer(printer, 2); 4499 if (!W_ERROR_IS_OK(status)) { 4500 DEBUG(10,("save_driver_init_2: error setting DEVMODE on printer [%s]\n", 4501 printer->info_2->printername)); 4502 } 4503 4504 done: 4505 talloc_destroy(ctx); 4506 free_nt_devicemode( &nt_devmode ); 4507 4508 printer->info_2->devmode = tmp_devmode; 4509 4510 return status; 4511 } 4512 4513 /**************************************************************************** 4514 Update the driver init info (DEVMODE and specifics) for a printer 4515 ****************************************************************************/ 4516 4517 WERROR save_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level, uint8 *data, uint32 data_len) 4518 { 4519 WERROR status = WERR_OK; 4520 4521 switch (level) { 4522 case 2: 4523 status = save_driver_init_2( printer, data, data_len ); 4524 break; 4525 default: 4526 status = WERR_UNKNOWN_LEVEL; 4527 break; 4528 } 4529 4530 return status; 4531 } 4532 4533 /**************************************************************************** 4534 Get a NT_PRINTER_INFO_LEVEL struct. It returns malloced memory. 4535 4536 Previously the code had a memory allocation problem because it always 4537 used the TALLOC_CTX from the Printer_entry*. This context lasts 4538 as a long as the original handle is open. So if the client made a lot 4539 of getprinter[data]() calls, the memory usage would climb. Now we use 4540 a short lived TALLOC_CTX for printer_info_2 objects returned. We 4541 still use the Printer_entry->ctx for maintaining the cache copy though 4542 since that object must live as long as the handle by definition. 4543 --jerry 4544 4545 ****************************************************************************/ 4546 4547 static WERROR get_a_printer_internal( Printer_entry *print_hnd, NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level, 4548 const char *sharename, bool get_loc_com) 4549 { 4550 WERROR result; 4551 fstring servername; 4552 4553 DEBUG(10,("get_a_printer: [%s] level %u\n", sharename, (unsigned int)level)); 4554 4555 if ( !(*pp_printer = TALLOC_ZERO_P(NULL, NT_PRINTER_INFO_LEVEL)) ) { 4556 DEBUG(0,("get_a_printer: talloc() fail.\n")); 4557 return WERR_NOMEM; 4558 } 4559 4560 switch (level) { 4561 case 2: 4562 if ( !((*pp_printer)->info_2 = TALLOC_ZERO_P(*pp_printer, NT_PRINTER_INFO_LEVEL_2)) ) { 4563 DEBUG(0,("get_a_printer: talloc() fail.\n")); 4564 TALLOC_FREE( *pp_printer ); 4565 return WERR_NOMEM; 4566 } 4567 4568 if ( print_hnd ) 4569 fstrcpy( servername, print_hnd->servername ); 4570 else { 4571 fstrcpy( servername, "%L" ); 4572 standard_sub_basic( "", "", servername, 4573 sizeof(servername)-1 ); 4574 } 4575 4576 result = get_a_printer_2( (*pp_printer)->info_2, 4577 servername, sharename, get_loc_com); 4578 4579 /* we have a new printer now. Save it with this handle */ 4580 4581 if ( !W_ERROR_IS_OK(result) ) { 4582 TALLOC_FREE( *pp_printer ); 4583 DEBUG(10,("get_a_printer: [%s] level %u returning %s\n", 4584 sharename, (unsigned int)level, win_errstr(result))); 4585 return result; 4586 } 4587 4588 dump_a_printer( *pp_printer, level); 4589 4590 break; 4591 4592 default: 4593 TALLOC_FREE( *pp_printer ); 4594 return WERR_UNKNOWN_LEVEL; 4595 } 4596 4597 return WERR_OK; 4598 } 4599 4600 WERROR get_a_printer( Printer_entry *print_hnd, 4601 NT_PRINTER_INFO_LEVEL **pp_printer, 4602 uint32 level, 4603 const char *sharename) 4604 { 4605 return get_a_printer_internal(print_hnd, pp_printer, level, 4606 sharename, true); 4607 } 4608 4609 WERROR get_a_printer_search( Printer_entry *print_hnd, 4610 NT_PRINTER_INFO_LEVEL **pp_printer, 4611 uint32 level, 4612 const char *sharename) 4613 { 4614 return get_a_printer_internal(print_hnd, pp_printer, level, 4615 sharename, false); 4616 } 4617 4618 /**************************************************************************** 4619 Deletes a NT_PRINTER_INFO_LEVEL struct. 4620 ****************************************************************************/ 4621 4622 uint32 free_a_printer(NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level) 4623 { 4624 NT_PRINTER_INFO_LEVEL *printer = *pp_printer; 4625 4626 if ( !printer ) 4627 return 0; 4628 4629 switch (level) { 4630 case 2: 4631 if ( printer->info_2 ) 4632 free_nt_printer_info_level_2(&printer->info_2); 4633 break; 4634 4635 default: 4636 DEBUG(0,("free_a_printer: unknown level! [%d]\n", level )); 4637 return 1; 4638 } 4639 4640 TALLOC_FREE(*pp_printer); 4641 4642 return 0; 4643 } 4644 4645 /**************************************************************************** 4646 ****************************************************************************/ 4647 4648 uint32_t add_a_printer_driver(TALLOC_CTX *mem_ctx, 4649 struct spoolss_AddDriverInfoCtr *r, 4650 char **driver_name, 4651 uint32_t *version) 4652 { 4653 struct spoolss_DriverInfo8 info8; 4654 4655 ZERO_STRUCT(info8); 4656 4657 DEBUG(10,("adding a printer at level [%d]\n", r->level)); 4658 4659 switch (r->level) { 4660 case 3: 4661 info8.version = r->info.info3->version; 4662 info8.driver_name = r->info.info3->driver_name; 4663 info8.architecture = r->info.info3->architecture; 4664 info8.driver_path = r->info.info3->driver_path; 4665 info8.data_file = r->info.info3->data_file; 4666 info8.config_file = r->info.info3->config_file; 4667 info8.help_file = r->info.info3->help_file; 4668 info8.monitor_name = r->info.info3->monitor_name; 4669 info8.default_datatype = r->info.info3->default_datatype; 4670 if (r->info.info3->dependent_files && r->info.info3->dependent_files->string) { 4671 info8.dependent_files = r->info.info3->dependent_files->string; 4672 } 4673 break; 4674 case 6: 4675 info8.version = r->info.info6->version; 4676 info8.driver_name = r->info.info6->driver_name; 4677 info8.architecture = r->info.info6->architecture; 4678 info8.driver_path = r->info.info6->driver_path; 4679 info8.data_file = r->info.info6->data_file; 4680 info8.config_file = r->info.info6->config_file; 4681 info8.help_file = r->info.info6->help_file; 4682 info8.monitor_name = r->info.info6->monitor_name; 4683 info8.default_datatype = r->info.info6->default_datatype; 4684 if (r->info.info6->dependent_files && r->info.info6->dependent_files->string) { 4685 info8.dependent_files = r->info.info6->dependent_files->string; 4686 } 4687 info8.driver_date = r->info.info6->driver_date; 4688 info8.driver_version = r->info.info6->driver_version; 4689 info8.manufacturer_name = r->info.info6->manufacturer_name; 4690 info8.manufacturer_url = r->info.info6->manufacturer_url; 4691 info8.hardware_id = r->info.info6->hardware_id; 4692 info8.provider = r->info.info6->provider; 4693 break; 4694 case 8: 4695 info8.version = r->info.info8->version; 4696 info8.driver_name = r->info.info8->driver_name; 4697 info8.architecture = r->info.info8->architecture; 4698 info8.driver_path = r->info.info8->driver_path; 4699 info8.data_file = r->info.info8->data_file; 4700 info8.config_file = r->info.info8->config_file; 4701 info8.help_file = r->info.info8->help_file; 4702 info8.monitor_name = r->info.info8->monitor_name; 4703 info8.default_datatype = r->info.info8->default_datatype; 4704 if (r->info.info8->dependent_files && r->info.info8->dependent_files->string) { 4705 info8.dependent_files = r->info.info8->dependent_files->string; 4706 } 4707 if (r->info.info8->previous_names && r->info.info8->previous_names->string) { 4708 info8.previous_names = r->info.info8->previous_names->string; 4709 } 4710 info8.driver_date = r->info.info8->driver_date; 4711 info8.driver_version = r->info.info8->driver_version; 4712 info8.manufacturer_name = r->info.info8->manufacturer_name; 4713 info8.manufacturer_url = r->info.info8->manufacturer_url; 4714 info8.hardware_id = r->info.info8->hardware_id; 4715 info8.provider = r->info.info8->provider; 4716 info8.print_processor = r->info.info8->print_processor; 4717 info8.vendor_setup = r->info.info8->vendor_setup; 4718 if (r->info.info8->color_profiles && r->info.info8->color_profiles->string) { 4719 info8.color_profiles = r->info.info8->color_profiles->string; 4720 } 4721 info8.inf_path = r->info.info8->inf_path; 4722 info8.printer_driver_attributes = r->info.info8->printer_driver_attributes; 4723 if (r->info.info8->core_driver_dependencies && r->info.info8->core_driver_dependencies->string) { 4724 info8.core_driver_dependencies = r->info.info8->core_driver_dependencies->string; 4725 } 4726 info8.min_inbox_driver_ver_date = r->info.info8->min_inbox_driver_ver_date; 4727 info8.min_inbox_driver_ver_version = r->info.info8->min_inbox_driver_ver_version; 4728 break; 4729 default: 4730 return -1; 4731 } 4732 4733 *driver_name = talloc_strdup(mem_ctx, info8.driver_name); 4734 if (!*driver_name) { 4735 return -1; 4736 } 4737 *version = info8.version; 4738 4739 return add_a_printer_driver_8(&info8); 4740 } 4741 4742 /**************************************************************************** 4743 ****************************************************************************/ 4744 4745 WERROR get_a_printer_driver(TALLOC_CTX *mem_ctx, 4746 struct spoolss_DriverInfo8 **driver, 4747 const char *drivername, const char *architecture, 4748 uint32_t version) 4749 { 4750 WERROR result; 4751 struct spoolss_DriverInfo3 info3; 4752 struct spoolss_DriverInfo8 *info8; 4753 4754 ZERO_STRUCT(info3); 4755 4756 /* Sometime we just want any version of the driver */ 4757 4758 if (version == DRIVER_ANY_VERSION) { 4759 /* look for Win2k first and then for NT4 */ 4760 result = get_a_printer_driver_3(mem_ctx, 4761 &info3, 4762 drivername, 4763 architecture, 3); 4764 if (!W_ERROR_IS_OK(result)) { 4765 result = get_a_printer_driver_3(mem_ctx, 4766 &info3, 4767 drivername, 4768 architecture, 2); 4769 } 4770 } else { 4771 result = get_a_printer_driver_3(mem_ctx, 4772 &info3, 4773 drivername, 4774 architecture, 4775 version); 4776 } 4777 4778 if (!W_ERROR_IS_OK(result)) { 4779 return result; 4780 } 4781 4782 info8 = talloc_zero(mem_ctx, struct spoolss_DriverInfo8); 4783 if (!info8) { 4784 return WERR_NOMEM; 4785 } 4786 4787 info8->version = info3.version; 4788 info8->driver_name = info3.driver_name; 4789 info8->architecture = info3.architecture; 4790 info8->driver_path = info3.driver_path; 4791 info8->data_file = info3.data_file; 4792 info8->config_file = info3.config_file; 4793 info8->help_file = info3.help_file; 4794 info8->dependent_files = info3.dependent_files; 4795 info8->monitor_name = info3.monitor_name; 4796 info8->default_datatype = info3.default_datatype; 4797 4798 *driver = info8; 4799 4800 return WERR_OK; 4801 } 4802 4803 /**************************************************************************** 4804 ****************************************************************************/ 4805 4806 uint32_t free_a_printer_driver(struct spoolss_DriverInfo8 *driver) 4807 { 4808 talloc_free(driver); 4809 return 0; 4810 } 4811 1168 return err; 1169 } 4812 1170 4813 1171 /**************************************************************************** … … 4816 1174 ****************************************************************************/ 4817 1175 4818 bool printer_driver_in_use(const struct spoolss_DriverInfo8 *r) 1176 bool printer_driver_in_use(TALLOC_CTX *mem_ctx, 1177 const struct auth_serversupplied_info *session_info, 1178 struct messaging_context *msg_ctx, 1179 const struct spoolss_DriverInfo8 *r) 4819 1180 { 4820 1181 int snum; 4821 1182 int n_services = lp_numservices(); 4822 NT_PRINTER_INFO_LEVEL *printer = NULL;4823 1183 bool in_use = False; 1184 struct spoolss_PrinterInfo2 *pinfo2 = NULL; 1185 WERROR result; 1186 struct dcerpc_binding_handle *b = NULL; 4824 1187 4825 1188 if (!r) { … … 4832 1195 4833 1196 for (snum=0; snum<n_services && !in_use; snum++) { 4834 if ( !(lp_snum_ok(snum) && lp_print_ok(snum) ) )1197 if (!lp_snum_ok(snum) || !lp_print_ok(snum)) { 4835 1198 continue; 4836 4837 if ( !W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, lp_servicename(snum))) ) 4838 continue; 4839 4840 if (strequal(r->driver_name, printer->info_2->drivername)) 1199 } 1200 1201 if (b == NULL) { 1202 result = winreg_printer_binding_handle(mem_ctx, 1203 session_info, 1204 msg_ctx, 1205 &b); 1206 if (!W_ERROR_IS_OK(result)) { 1207 return false; 1208 } 1209 } 1210 1211 result = winreg_get_printer(mem_ctx, b, 1212 lp_servicename(snum), 1213 &pinfo2); 1214 if (!W_ERROR_IS_OK(result)) { 1215 continue; /* skip */ 1216 } 1217 1218 if (strequal(r->driver_name, pinfo2->drivername)) { 4841 1219 in_use = True; 4842 4843 free_a_printer( &printer, 2 ); 1220 } 1221 1222 TALLOC_FREE(pinfo2); 4844 1223 } 4845 1224 … … 4847 1226 4848 1227 if ( in_use ) { 4849 struct spoolss_DriverInfo8 *d ;1228 struct spoolss_DriverInfo8 *driver; 4850 1229 WERROR werr; 4851 1230 … … 4856 1235 4857 1236 if (!strequal("Windows NT x86", r->architecture)) { 4858 werr = get_a_printer_driver(talloc_tos(), &d, r->driver_name, "Windows NT x86", DRIVER_ANY_VERSION); 4859 } 4860 else { 4861 switch (r->version) { 4862 case 2: 4863 werr = get_a_printer_driver(talloc_tos(), &d, r->driver_name, "Windows NT x86", 3); 4864 break; 4865 case 3: 4866 werr = get_a_printer_driver(talloc_tos(), &d, r->driver_name, "Windows NT x86", 2); 4867 break; 4868 default: 4869 DEBUG(0,("printer_driver_in_use: ERROR! unknown driver version (%d)\n", 4870 r->version)); 4871 werr = WERR_UNKNOWN_PRINTER_DRIVER; 4872 break; 4873 } 1237 werr = winreg_get_driver(mem_ctx, b, 1238 "Windows NT x86", 1239 r->driver_name, 1240 DRIVER_ANY_VERSION, 1241 &driver); 1242 } else if (r->version == 2) { 1243 werr = winreg_get_driver(mem_ctx, b, 1244 "Windows NT x86", 1245 r->driver_name, 1246 3, &driver); 1247 } else if (r->version == 3) { 1248 werr = winreg_get_driver(mem_ctx, b, 1249 "Windows NT x86", 1250 r->driver_name, 1251 2, &driver); 1252 } else { 1253 DEBUG(0, ("printer_driver_in_use: ERROR!" 1254 " unknown driver version (%d)\n", 1255 r->version)); 1256 werr = WERR_UNKNOWN_PRINTER_DRIVER; 4874 1257 } 4875 1258 … … 4879 1262 /* it's ok to remove the driver, we have other architctures left */ 4880 1263 in_use = False; 4881 free_a_printer_driver(d);1264 talloc_free(driver); 4882 1265 } 4883 1266 } … … 5031 1414 5032 1415 bool printer_driver_files_in_use(TALLOC_CTX *mem_ctx, 1416 const struct auth_serversupplied_info *session_info, 1417 struct messaging_context *msg_ctx, 5033 1418 struct spoolss_DriverInfo8 *info) 5034 1419 { 5035 1420 int i; 5036 int ndrivers;5037 1421 uint32 version; 5038 fstring *list = NULL;5039 1422 struct spoolss_DriverInfo8 *driver; 5040 1423 bool in_use = false; 1424 uint32_t num_drivers; 1425 const char **drivers; 1426 WERROR result; 1427 struct dcerpc_binding_handle *b; 5041 1428 5042 1429 if ( !info ) … … 5047 1434 /* loop over all driver versions */ 5048 1435 5049 DEBUG(5,("printer_driver_files_in_use: Beginning search through ntdrivers.tdb...\n"));1436 DEBUG(5,("printer_driver_files_in_use: Beginning search of drivers...\n")); 5050 1437 5051 1438 /* get the list of drivers */ 5052 1439 5053 list = NULL; 5054 ndrivers = get_ntdrivers(&list, info->architecture, version); 5055 5056 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", 5057 ndrivers, info->architecture, version)); 1440 result = winreg_printer_binding_handle(mem_ctx, 1441 session_info, 1442 msg_ctx, 1443 &b); 1444 if (!W_ERROR_IS_OK(result)) { 1445 return false; 1446 } 1447 1448 result = winreg_get_driver_list(mem_ctx, b, 1449 info->architecture, version, 1450 &num_drivers, &drivers); 1451 if (!W_ERROR_IS_OK(result)) { 1452 return true; 1453 } 1454 1455 DEBUGADD(4, ("we have:[%d] drivers in environment [%s] and version [%d]\n", 1456 num_drivers, info->architecture, version)); 5058 1457 5059 1458 /* check each driver for overlap in files */ 5060 1459 5061 for (i =0; i<ndrivers; i++) {5062 DEBUGADD(5,("\tdriver: [%s]\n", list[i]));1460 for (i = 0; i < num_drivers; i++) { 1461 DEBUGADD(5,("\tdriver: [%s]\n", drivers[i])); 5063 1462 5064 1463 driver = NULL; 5065 1464 5066 if (!W_ERROR_IS_OK(get_a_printer_driver(talloc_tos(), &driver, list[i], info->architecture, version))) { 5067 SAFE_FREE(list); 1465 result = winreg_get_driver(mem_ctx, b, 1466 info->architecture, drivers[i], 1467 version, &driver); 1468 if (!W_ERROR_IS_OK(result)) { 1469 talloc_free(drivers); 5068 1470 return True; 5069 1471 } … … 5081 1483 } 5082 1484 5083 free_a_printer_driver(driver);5084 } 5085 5086 SAFE_FREE(list);5087 5088 DEBUG(5,("printer_driver_files_in_use: Completed search through ntdrivers.tdb...\n"));1485 talloc_free(driver); 1486 } 1487 1488 talloc_free(drivers); 1489 1490 DEBUG(5,("printer_driver_files_in_use: Completed search of drivers...\n")); 5089 1491 5090 1492 return in_use; … … 5115 1517 ****************************************************************************/ 5116 1518 5117 static bool delete_driver_files(struct pipes_struct *rpc_pipe,5118 1519 bool delete_driver_files(const struct auth_serversupplied_info *session_info, 1520 const struct spoolss_DriverInfo8 *r) 5119 1521 { 5120 1522 int i = 0; … … 5124 1526 NTSTATUS nt_status; 5125 1527 char *oldcwd; 5126 fstring printdollar;1528 char *printdollar = NULL; 5127 1529 int printdollar_snum; 5128 1530 bool ret = false; … … 5135 1537 r->driver_name, r->version)); 5136 1538 5137 fstrcpy(printdollar, "print$"); 5138 5139 printdollar_snum = find_service(printdollar); 1539 printdollar_snum = find_service(talloc_tos(), "print$", &printdollar); 1540 if (!printdollar) { 1541 return false; 1542 } 5140 1543 if (printdollar_snum == -1) { 5141 1544 return false; … … 5144 1547 nt_status = create_conn_struct(talloc_tos(), &conn, printdollar_snum, 5145 1548 lp_pathname(printdollar_snum), 5146 rpc_pipe->server_info, &oldcwd);1549 session_info, &oldcwd); 5147 1550 if (!NT_STATUS_IS_OK(nt_status)) { 5148 1551 DEBUG(0,("delete_driver_files: create_conn_struct " … … 5151 1554 } 5152 1555 1556 nt_status = set_conn_force_user_group(conn, printdollar_snum); 1557 if (!NT_STATUS_IS_OK(nt_status)) { 1558 DEBUG(0, ("failed set force user / group\n")); 1559 ret = false; 1560 goto err_free_conn; 1561 } 1562 1563 if (!become_user_by_session(conn, session_info)) { 1564 DEBUG(0, ("failed to become user\n")); 1565 ret = false; 1566 goto err_free_conn; 1567 } 1568 5153 1569 if ( !CAN_WRITE(conn) ) { 5154 1570 DEBUG(3,("delete_driver_files: Cannot delete print driver when [print$] is read-only\n")); 5155 goto fail; 1571 ret = false; 1572 goto err_out; 5156 1573 } 5157 1574 … … 5209 1626 } 5210 1627 5211 goto done;5212 fail:5213 ret = false;5214 done:1628 ret = true; 1629 err_out: 1630 unbecome_user(); 1631 err_free_conn: 5215 1632 if (conn != NULL) { 5216 1633 vfs_ChDir(conn, oldcwd); 1634 SMB_VFS_DISCONNECT(conn); 5217 1635 conn_free(conn); 5218 1636 } 5219 1637 return ret; 5220 }5221 5222 /****************************************************************************5223 Remove a printer driver from the TDB. This assumes that the the driver was5224 previously looked up.5225 ***************************************************************************/5226 5227 WERROR delete_printer_driver(struct pipes_struct *rpc_pipe,5228 const struct spoolss_DriverInfo8 *r,5229 uint32 version, bool delete_files )5230 {5231 char *key = NULL;5232 const char *arch;5233 TDB_DATA dbuf;5234 5235 /* delete the tdb data first */5236 5237 arch = get_short_archi(r->architecture);5238 if (!arch) {5239 return WERR_UNKNOWN_PRINTER_DRIVER;5240 }5241 if (asprintf(&key, "%s%s/%d/%s", DRIVERS_PREFIX,5242 arch, version, r->driver_name) < 0) {5243 return WERR_NOMEM;5244 }5245 5246 DEBUG(5,("delete_printer_driver: key = [%s] delete_files = %s\n",5247 key, delete_files ? "TRUE" : "FALSE" ));5248 5249 /* check if the driver actually exists for this environment */5250 5251 dbuf = tdb_fetch_bystring( tdb_drivers, key );5252 if ( !dbuf.dptr ) {5253 DEBUG(8,("delete_printer_driver: Driver unknown [%s]\n", key));5254 SAFE_FREE(key);5255 return WERR_UNKNOWN_PRINTER_DRIVER;5256 }5257 5258 SAFE_FREE( dbuf.dptr );5259 5260 /* ok... the driver exists so the delete should return success */5261 5262 if (tdb_delete_bystring(tdb_drivers, key) == -1) {5263 DEBUG (0,("delete_printer_driver: fail to delete %s!\n", key));5264 SAFE_FREE(key);5265 return WERR_ACCESS_DENIED;5266 }5267 5268 /*5269 * now delete any associated files if delete_files == True5270 * even if this part failes, we return succes because the5271 * driver doesn not exist any more5272 */5273 5274 if ( delete_files )5275 delete_driver_files(rpc_pipe, r);5276 5277 DEBUG(5,("delete_printer_driver: driver delete successful [%s]\n", key));5278 SAFE_FREE(key);5279 5280 return WERR_OK;5281 }5282 5283 /****************************************************************************5284 Store a security desc for a printer.5285 ****************************************************************************/5286 5287 WERROR nt_printing_setsec(const char *sharename, SEC_DESC_BUF *secdesc_ctr)5288 {5289 SEC_DESC_BUF *new_secdesc_ctr = NULL;5290 SEC_DESC_BUF *old_secdesc_ctr = NULL;5291 TALLOC_CTX *mem_ctx = NULL;5292 TDB_DATA kbuf;5293 TDB_DATA dbuf;5294 DATA_BLOB blob;5295 WERROR status;5296 NTSTATUS nt_status;5297 5298 mem_ctx = talloc_init("nt_printing_setsec");5299 if (mem_ctx == NULL)5300 return WERR_NOMEM;5301 5302 /* The old owner and group sids of the security descriptor are not5303 present when new ACEs are added or removed by changing printer5304 permissions through NT. If they are NULL in the new security5305 descriptor then copy them over from the old one. */5306 5307 if (!secdesc_ctr->sd->owner_sid || !secdesc_ctr->sd->group_sid) {5308 DOM_SID *owner_sid, *group_sid;5309 SEC_ACL *dacl, *sacl;5310 SEC_DESC *psd = NULL;5311 size_t size;5312 5313 if (!nt_printing_getsec(mem_ctx, sharename, &old_secdesc_ctr)) {5314 status = WERR_NOMEM;5315 goto out;5316 }5317 5318 /* Pick out correct owner and group sids */5319 5320 owner_sid = secdesc_ctr->sd->owner_sid ?5321 secdesc_ctr->sd->owner_sid :5322 old_secdesc_ctr->sd->owner_sid;5323 5324 group_sid = secdesc_ctr->sd->group_sid ?5325 secdesc_ctr->sd->group_sid :5326 old_secdesc_ctr->sd->group_sid;5327 5328 dacl = secdesc_ctr->sd->dacl ?5329 secdesc_ctr->sd->dacl :5330 old_secdesc_ctr->sd->dacl;5331 5332 sacl = secdesc_ctr->sd->sacl ?5333 secdesc_ctr->sd->sacl :5334 old_secdesc_ctr->sd->sacl;5335 5336 /* Make a deep copy of the security descriptor */5337 5338 psd = make_sec_desc(mem_ctx, secdesc_ctr->sd->revision, secdesc_ctr->sd->type,5339 owner_sid, group_sid,5340 sacl,5341 dacl,5342 &size);5343 5344 if (!psd) {5345 status = WERR_NOMEM;5346 goto out;5347 }5348 5349 new_secdesc_ctr = make_sec_desc_buf(mem_ctx, size, psd);5350 }5351 5352 if (!new_secdesc_ctr) {5353 new_secdesc_ctr = secdesc_ctr;5354 }5355 5356 /* Store the security descriptor in a tdb */5357 5358 nt_status = marshall_sec_desc_buf(mem_ctx, new_secdesc_ctr,5359 &blob.data, &blob.length);5360 if (!NT_STATUS_IS_OK(nt_status)) {5361 status = ntstatus_to_werror(nt_status);5362 goto out;5363 }5364 5365 kbuf = make_printers_secdesc_tdbkey(mem_ctx, sharename );5366 5367 dbuf.dptr = (unsigned char *)blob.data;5368 dbuf.dsize = blob.length;5369 5370 if (tdb_trans_store(tdb_printers, kbuf, dbuf, TDB_REPLACE)==0) {5371 status = WERR_OK;5372 } else {5373 DEBUG(1,("Failed to store secdesc for %s\n", sharename));5374 status = WERR_BADFUNC;5375 }5376 5377 /* Free malloc'ed memory */5378 talloc_free(blob.data);5379 5380 out:5381 5382 if (mem_ctx)5383 talloc_destroy(mem_ctx);5384 return status;5385 }5386 5387 /****************************************************************************5388 Construct a default security descriptor buffer for a printer.5389 ****************************************************************************/5390 5391 static SEC_DESC_BUF *construct_default_printer_sdb(TALLOC_CTX *ctx)5392 {5393 SEC_ACE ace[5]; /* max number of ace entries */5394 int i = 0;5395 uint32_t sa;5396 SEC_ACL *psa = NULL;5397 SEC_DESC_BUF *sdb = NULL;5398 SEC_DESC *psd = NULL;5399 DOM_SID adm_sid;5400 size_t sd_size;5401 5402 /* Create an ACE where Everyone is allowed to print */5403 5404 sa = PRINTER_ACE_PRINT;5405 init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,5406 sa, SEC_ACE_FLAG_CONTAINER_INHERIT);5407 5408 /* Add the domain admins group if we are a DC */5409 5410 if ( IS_DC ) {5411 DOM_SID domadmins_sid;5412 5413 sid_copy(&domadmins_sid, get_global_sam_sid());5414 sid_append_rid(&domadmins_sid, DOMAIN_GROUP_RID_ADMINS);5415 5416 sa = PRINTER_ACE_FULL_CONTROL;5417 init_sec_ace(&ace[i++], &domadmins_sid,5418 SEC_ACE_TYPE_ACCESS_ALLOWED, sa,5419 SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY);5420 init_sec_ace(&ace[i++], &domadmins_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,5421 sa, SEC_ACE_FLAG_CONTAINER_INHERIT);5422 }5423 else if (secrets_fetch_domain_sid(lp_workgroup(), &adm_sid)) {5424 sid_append_rid(&adm_sid, DOMAIN_USER_RID_ADMIN);5425 5426 sa = PRINTER_ACE_FULL_CONTROL;5427 init_sec_ace(&ace[i++], &adm_sid,5428 SEC_ACE_TYPE_ACCESS_ALLOWED, sa,5429 SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY);5430 init_sec_ace(&ace[i++], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,5431 sa, SEC_ACE_FLAG_CONTAINER_INHERIT);5432 }5433 5434 /* add BUILTIN\Administrators as FULL CONTROL */5435 5436 sa = PRINTER_ACE_FULL_CONTROL;5437 init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,5438 SEC_ACE_TYPE_ACCESS_ALLOWED, sa,5439 SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY);5440 init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,5441 SEC_ACE_TYPE_ACCESS_ALLOWED,5442 sa, SEC_ACE_FLAG_CONTAINER_INHERIT);5443 5444 /* Make the security descriptor owned by the BUILTIN\Administrators */5445 5446 /* The ACL revision number in rpc_secdesc.h differs from the one5447 created by NT when setting ACE entries in printer5448 descriptors. NT4 complains about the property being edited by a5449 NT5 machine. */5450 5451 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace)) != NULL) {5452 psd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE,5453 &global_sid_Builtin_Administrators,5454 &global_sid_Builtin_Administrators,5455 NULL, psa, &sd_size);5456 }5457 5458 if (!psd) {5459 DEBUG(0,("construct_default_printer_sd: Failed to make SEC_DESC.\n"));5460 return NULL;5461 }5462 5463 sdb = make_sec_desc_buf(ctx, sd_size, psd);5464 5465 DEBUG(4,("construct_default_printer_sdb: size = %u.\n",5466 (unsigned int)sd_size));5467 5468 return sdb;5469 }5470 5471 /****************************************************************************5472 Get a security desc for a printer.5473 ****************************************************************************/5474 5475 bool nt_printing_getsec(TALLOC_CTX *ctx, const char *sharename, SEC_DESC_BUF **secdesc_ctr)5476 {5477 TDB_DATA kbuf;5478 TDB_DATA dbuf;5479 DATA_BLOB blob;5480 char *temp;5481 NTSTATUS status;5482 5483 if (strlen(sharename) > 2 && (temp = strchr(sharename + 2, '\\'))) {5484 sharename = temp + 1;5485 }5486 5487 /* Fetch security descriptor from tdb */5488 5489 kbuf = make_printers_secdesc_tdbkey(ctx, sharename);5490 5491 dbuf = tdb_fetch(tdb_printers, kbuf);5492 if (dbuf.dptr) {5493 5494 status = unmarshall_sec_desc_buf(ctx, dbuf.dptr, dbuf.dsize,5495 secdesc_ctr);5496 SAFE_FREE(dbuf.dptr);5497 5498 if (NT_STATUS_IS_OK(status)) {5499 return true;5500 }5501 }5502 5503 *secdesc_ctr = construct_default_printer_sdb(ctx);5504 if (!*secdesc_ctr) {5505 return false;5506 }5507 5508 status = marshall_sec_desc_buf(ctx, *secdesc_ctr,5509 &blob.data, &blob.length);5510 if (NT_STATUS_IS_OK(status)) {5511 dbuf.dptr = (unsigned char *)blob.data;5512 dbuf.dsize = blob.length;5513 tdb_trans_store(tdb_printers, kbuf, dbuf, TDB_REPLACE);5514 talloc_free(blob.data);5515 }5516 5517 /* If security descriptor is owned by S-1-1-0 and winbindd is up,5518 this security descriptor has been created when winbindd was5519 down. Take ownership of security descriptor. */5520 5521 if (sid_equal((*secdesc_ctr)->sd->owner_sid, &global_sid_World)) {5522 DOM_SID owner_sid;5523 5524 /* Change sd owner to workgroup administrator */5525 5526 if (secrets_fetch_domain_sid(lp_workgroup(), &owner_sid)) {5527 SEC_DESC_BUF *new_secdesc_ctr = NULL;5528 SEC_DESC *psd = NULL;5529 size_t size;5530 5531 /* Create new sd */5532 5533 sid_append_rid(&owner_sid, DOMAIN_USER_RID_ADMIN);5534 5535 psd = make_sec_desc(ctx, (*secdesc_ctr)->sd->revision, (*secdesc_ctr)->sd->type,5536 &owner_sid,5537 (*secdesc_ctr)->sd->group_sid,5538 (*secdesc_ctr)->sd->sacl,5539 (*secdesc_ctr)->sd->dacl,5540 &size);5541 5542 if (!psd) {5543 return False;5544 }5545 5546 new_secdesc_ctr = make_sec_desc_buf(ctx, size, psd);5547 if (!new_secdesc_ctr) {5548 return False;5549 }5550 5551 /* Swap with other one */5552 5553 *secdesc_ctr = new_secdesc_ctr;5554 5555 /* Set it */5556 5557 nt_printing_setsec(sharename, *secdesc_ctr);5558 }5559 }5560 5561 if (DEBUGLEVEL >= 10) {5562 SEC_ACL *the_acl = (*secdesc_ctr)->sd->dacl;5563 int i;5564 5565 DEBUG(10, ("secdesc_ctr for %s has %d aces:\n",5566 sharename, the_acl->num_aces));5567 5568 for (i = 0; i < the_acl->num_aces; i++) {5569 DEBUG(10, ("%s %d %d 0x%08x\n",5570 sid_string_dbg(&the_acl->aces[i].trustee),5571 the_acl->aces[i].type, the_acl->aces[i].flags,5572 the_acl->aces[i].access_mask));5573 }5574 }5575 5576 return True;5577 1638 } 5578 1639 … … 5617 1678 NT5 the object specific ones. */ 5618 1679 5619 void map_printer_permissions( SEC_DESC*sd)1680 void map_printer_permissions(struct security_descriptor *sd) 5620 1681 { 5621 1682 int i; … … 5627 1688 } 5628 1689 5629 void map_job_permissions( SEC_DESC*sd)1690 void map_job_permissions(struct security_descriptor *sd) 5630 1691 { 5631 1692 int i; … … 5661 1722 5662 1723 ****************************************************************************/ 5663 bool print_access_check(struct auth_serversupplied_info *server_info, int snum, 1724 bool print_access_check(const struct auth_serversupplied_info *session_info, 1725 struct messaging_context *msg_ctx, int snum, 5664 1726 int access_type) 5665 1727 { 5666 SEC_DESC_BUF*secdesc = NULL;1728 struct spoolss_security_descriptor *secdesc = NULL; 5667 1729 uint32 access_granted; 1730 size_t sd_size; 5668 1731 NTSTATUS status; 1732 WERROR result; 5669 1733 const char *pname; 5670 1734 TALLOC_CTX *mem_ctx = NULL; 5671 SE_PRIV se_printop = SE_PRINT_OPERATOR;5672 1735 5673 1736 /* If user is NULL then use the current_user structure */ … … 5675 1738 /* Always allow root or SE_PRINT_OPERATROR to do anything */ 5676 1739 5677 if (se rver_info->utok.uid == sec_initial_uid()5678 || user_has_privileges(server_info->ptok, &se_printop )) {1740 if (session_info->utok.uid == sec_initial_uid() 1741 || security_token_has_privilege(session_info->security_token, SEC_PRIV_PRINT_OPERATOR)) { 5679 1742 return True; 5680 1743 } … … 5682 1745 /* Get printer name */ 5683 1746 5684 pname = PRINTERNAME(snum);1747 pname = lp_printername(snum); 5685 1748 5686 1749 if (!pname || !*pname) { … … 5696 1759 } 5697 1760 5698 if (!nt_printing_getsec(mem_ctx, pname, &secdesc)) { 1761 result = winreg_get_printer_secdesc_internal(mem_ctx, 1762 get_session_info_system(), 1763 msg_ctx, 1764 pname, 1765 &secdesc); 1766 if (!W_ERROR_IS_OK(result)) { 5699 1767 talloc_destroy(mem_ctx); 5700 1768 errno = ENOMEM; … … 5703 1771 5704 1772 if (access_type == JOB_ACCESS_ADMINISTER) { 5705 SEC_DESC_BUF*parent_secdesc = secdesc;1773 struct spoolss_security_descriptor *parent_secdesc = secdesc; 5706 1774 5707 1775 /* Create a child security descriptor to check permissions 5708 1776 against. This is because print jobs are child objects 5709 1777 objects of a printer. */ 5710 5711 status = se_create_child_secdesc_buf(mem_ctx, &secdesc, parent_secdesc->sd, False); 5712 1778 status = se_create_child_secdesc(mem_ctx, 1779 &secdesc, 1780 &sd_size, 1781 parent_secdesc, 1782 parent_secdesc->owner_sid, 1783 parent_secdesc->group_sid, 1784 false); 5713 1785 if (!NT_STATUS_IS_OK(status)) { 5714 1786 talloc_destroy(mem_ctx); … … 5717 1789 } 5718 1790 5719 map_job_permissions(secdesc ->sd);1791 map_job_permissions(secdesc); 5720 1792 } else { 5721 map_printer_permissions(secdesc ->sd);1793 map_printer_permissions(secdesc); 5722 1794 } 5723 1795 5724 1796 /* Check access */ 5725 status = se_access_check(secdesc ->sd, server_info->ptok, access_type,1797 status = se_access_check(secdesc, session_info->security_token, access_type, 5726 1798 &access_granted); 5727 1799 … … 5731 1803 5732 1804 if (!NT_STATUS_IS_OK(status) && 5733 (token_contains_name_in_list(uidtoname(server_info->utok.uid), 5734 pdb_get_domain(server_info->sam_account), 5735 NULL, 5736 server_info->ptok, 1805 (token_contains_name_in_list(uidtoname(session_info->utok.uid), 1806 session_info->info3->base.domain.string, 1807 NULL, session_info->security_token, 5737 1808 lp_printer_admin(snum)))) { 5738 1809 talloc_destroy(mem_ctx); … … 5753 1824 *****************************************************************************/ 5754 1825 5755 bool print_time_access_check(const char *servicename) 5756 { 5757 NT_PRINTER_INFO_LEVEL *printer = NULL; 1826 bool print_time_access_check(const struct auth_serversupplied_info *session_info, 1827 struct messaging_context *msg_ctx, 1828 const char *servicename) 1829 { 1830 struct spoolss_PrinterInfo2 *pinfo2 = NULL; 1831 WERROR result; 5758 1832 bool ok = False; 5759 1833 time_t now = time(NULL); … … 5761 1835 uint32 mins; 5762 1836 5763 if (!W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, servicename))) 1837 result = winreg_get_printer_internal(NULL, session_info, msg_ctx, 1838 servicename, &pinfo2); 1839 if (!W_ERROR_IS_OK(result)) { 5764 1840 return False; 5765 5766 if (printer->info_2->starttime == 0 && printer->info_2->untiltime == 0) 1841 } 1842 1843 if (pinfo2->starttime == 0 && pinfo2->untiltime == 0) { 5767 1844 ok = True; 1845 } 5768 1846 5769 1847 t = gmtime(&now); 5770 1848 mins = (uint32)t->tm_hour*60 + (uint32)t->tm_min; 5771 1849 5772 if (mins >= p rinter->info_2->starttime && mins <= printer->info_2->untiltime)1850 if (mins >= pinfo2->starttime && mins <= pinfo2->untiltime) { 5773 1851 ok = True; 5774 5775 free_a_printer(&printer, 2); 5776 5777 if (!ok) 1852 } 1853 1854 TALLOC_FREE(pinfo2); 1855 1856 if (!ok) { 5778 1857 errno = EACCES; 1858 } 5779 1859 5780 1860 return ok; 5781 1861 } 5782 1862 5783 /**************************************************************************** 5784 Fill in the servername sent in the _spoolss_open_printer_ex() call 5785 ****************************************************************************/ 5786 5787 char* get_server_name( Printer_entry *printer ) 5788 { 5789 return printer->servername; 5790 } 5791 5792 1863 void nt_printer_remove(TALLOC_CTX *mem_ctx, 1864 const struct auth_serversupplied_info *session_info, 1865 struct messaging_context *msg_ctx, 1866 const char *printer) 1867 { 1868 WERROR result; 1869 1870 result = winreg_delete_printer_key_internal(mem_ctx, session_info, msg_ctx, 1871 printer, ""); 1872 if (!W_ERROR_IS_OK(result)) { 1873 DEBUG(0, ("nt_printer_remove: failed to remove rpinter %s", 1874 printer)); 1875 } 1876 }
Note:
See TracChangeset
for help on using the changeset viewer.