2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Copyright (C) Andrew Tridgell 1992-2000,
5 * Copyright (C) Jean François Micouleau 1998-2000.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 extern DOM_SID global_sid_World
;
26 static TDB_CONTEXT
*tdb_forms
; /* used for forms files */
27 static TDB_CONTEXT
*tdb_drivers
; /* used for driver files */
28 static TDB_CONTEXT
*tdb_printers
; /* used for printers files */
30 #define FORMS_PREFIX "FORMS/"
31 #define DRIVERS_PREFIX "DRIVERS/"
32 #define DRIVER_INIT_PREFIX "DRIVER_INIT/"
33 #define PRINTERS_PREFIX "PRINTERS/"
34 #define SECDESC_PREFIX "SECDESC/"
35 #define GLOBAL_C_SETPRINTER "GLOBALS/c_setprinter"
37 #define NTDRIVERS_DATABASE_VERSION_1 1
38 #define NTDRIVERS_DATABASE_VERSION_2 2
39 #define NTDRIVERS_DATABASE_VERSION_3 3 /* little endian version of v2 */
41 #define NTDRIVERS_DATABASE_VERSION NTDRIVERS_DATABASE_VERSION_3
43 /* Map generic permissions to printer object specific permissions */
45 GENERIC_MAPPING printer_generic_mapping
= {
52 STANDARD_MAPPING printer_std_mapping
= {
59 /* Map generic permissions to print server object specific permissions */
61 GENERIC_MAPPING printserver_generic_mapping
= {
68 STANDARD_MAPPING printserver_std_mapping
= {
75 /* We need one default form to support our default printer. Msoft adds the
76 forms it wants and in the ORDER it wants them (note: DEVMODE papersize is an
77 array index). Letter is always first, so (for the current code) additions
78 always put things in the correct order. */
79 static nt_forms_struct default_forms
[] = {
80 {"Letter",0x1,0x34b5c,0x44368,0x0,0x0,0x34b5c,0x44368},
81 {"Letter Small",0x1,0x34b5c,0x44368,0x0,0x0,0x34b5c,0x44368},
82 {"Tabloid",0x1,0x44368,0x696b8,0x0,0x0,0x44368,0x696b8},
83 {"Ledger",0x1,0x696b8,0x44368,0x0,0x0,0x696b8,0x44368},
84 {"Legal",0x1,0x34b5c,0x56d10,0x0,0x0,0x34b5c,0x56d10},
85 {"Statement",0x1,0x221b4,0x34b5c,0x0,0x0,0x221b4,0x34b5c},
86 {"Executive",0x1,0x2cf56,0x411cc,0x0,0x0,0x2cf56,0x411cc},
87 {"A3",0x1,0x48828,0x668a0,0x0,0x0,0x48828,0x668a0},
88 {"A4",0x1,0x33450,0x48828,0x0,0x0,0x33450,0x48828},
89 {"A4 Small",0x1,0x33450,0x48828,0x0,0x0,0x33450,0x48828},
90 {"A5",0x1,0x24220,0x33450,0x0,0x0,0x24220,0x33450},
91 {"B4 (JIS)",0x1,0x3ebe8,0x58de0,0x0,0x0,0x3ebe8,0x58de0},
92 {"B5 (JIS)",0x1,0x2c6f0,0x3ebe8,0x0,0x0,0x2c6f0,0x3ebe8},
93 {"Folio",0x1,0x34b5c,0x509d8,0x0,0x0,0x34b5c,0x509d8},
94 {"Quarto",0x1,0x347d8,0x43238,0x0,0x0,0x347d8,0x43238},
95 {"10x14",0x1,0x3e030,0x56d10,0x0,0x0,0x3e030,0x56d10},
96 {"11x17",0x1,0x44368,0x696b8,0x0,0x0,0x44368,0x696b8},
97 {"Note",0x1,0x34b5c,0x44368,0x0,0x0,0x34b5c,0x44368},
98 {"Envelope #9",0x1,0x18079,0x37091,0x0,0x0,0x18079,0x37091},
99 {"Envelope #10",0x1,0x19947,0x3ae94,0x0,0x0,0x19947,0x3ae94},
100 {"Envelope #11",0x1,0x1be7c,0x40565,0x0,0x0,0x1be7c,0x40565},
101 {"Envelope #12",0x1,0x1d74a,0x44368,0x0,0x0,0x1d74a,0x44368},
102 {"Envelope #14",0x1,0x1f018,0x47504,0x0,0x0,0x1f018,0x47504},
103 {"C size sheet",0x1,0x696b8,0x886d0,0x0,0x0,0x696b8,0x886d0},
104 {"D size sheet",0x1,0x886d0,0xd2d70,0x0,0x0,0x886d0,0xd2d70},
105 {"E size sheet",0x1,0xd2d70,0x110da0,0x0,0x0,0xd2d70,0x110da0},
106 {"Envelope DL",0x1,0x1adb0,0x35b60,0x0,0x0,0x1adb0,0x35b60},
107 {"Envelope C5",0x1,0x278d0,0x37e88,0x0,0x0,0x278d0,0x37e88},
108 {"Envelope C3",0x1,0x4f1a0,0x6fd10,0x0,0x0,0x4f1a0,0x6fd10},
109 {"Envelope C4",0x1,0x37e88,0x4f1a0,0x0,0x0,0x37e88,0x4f1a0},
110 {"Envelope C6",0x1,0x1bd50,0x278d0,0x0,0x0,0x1bd50,0x278d0},
111 {"Envelope C65",0x1,0x1bd50,0x37e88,0x0,0x0,0x1bd50,0x37e88},
112 {"Envelope B4",0x1,0x3d090,0x562e8,0x0,0x0,0x3d090,0x562e8},
113 {"Envelope B5",0x1,0x2af80,0x3d090,0x0,0x0,0x2af80,0x3d090},
114 {"Envelope B6",0x1,0x2af80,0x1e848,0x0,0x0,0x2af80,0x1e848},
115 {"Envelope",0x1,0x1adb0,0x38270,0x0,0x0,0x1adb0,0x38270},
116 {"Envelope Monarch",0x1,0x18079,0x2e824,0x0,0x0,0x18079,0x2e824},
117 {"6 3/4 Envelope",0x1,0x167ab,0x284ec,0x0,0x0,0x167ab,0x284ec},
118 {"US Std Fanfold",0x1,0x5c3e1,0x44368,0x0,0x0,0x5c3e1,0x44368},
119 {"German Std Fanfold",0x1,0x34b5c,0x4a6a0,0x0,0x0,0x34b5c,0x4a6a0},
120 {"German Legal Fanfold",0x1,0x34b5c,0x509d8,0x0,0x0,0x34b5c,0x509d8},
121 {"B4 (ISO)",0x1,0x3d090,0x562e8,0x0,0x0,0x3d090,0x562e8},
122 {"Japanese Postcard",0x1,0x186a0,0x24220,0x0,0x0,0x186a0,0x24220},
123 {"9x11",0x1,0x37cf8,0x44368,0x0,0x0,0x37cf8,0x44368},
124 {"10x11",0x1,0x3e030,0x44368,0x0,0x0,0x3e030,0x44368},
125 {"15x11",0x1,0x5d048,0x44368,0x0,0x0,0x5d048,0x44368},
126 {"Envelope Invite",0x1,0x35b60,0x35b60,0x0,0x0,0x35b60,0x35b60},
127 {"Reserved48",0x1,0x1,0x1,0x0,0x0,0x1,0x1},
128 {"Reserved49",0x1,0x1,0x1,0x0,0x0,0x1,0x1},
129 {"Letter Extra",0x1,0x3ae94,0x4a6a0,0x0,0x0,0x3ae94,0x4a6a0},
130 {"Legal Extra",0x1,0x3ae94,0x5d048,0x0,0x0,0x3ae94,0x5d048},
131 {"Tabloid Extra",0x1,0x4a6a0,0x6f9f0,0x0,0x0,0x4a6a0,0x6f9f0},
132 {"A4 Extra",0x1,0x397c2,0x4eb16,0x0,0x0,0x397c2,0x4eb16},
133 {"Letter Transverse",0x1,0x34b5c,0x44368,0x0,0x0,0x34b5c,0x44368},
134 {"A4 Transverse",0x1,0x33450,0x48828,0x0,0x0,0x33450,0x48828},
135 {"Letter Extra Transverse",0x1,0x3ae94,0x4a6a0,0x0,0x0,0x3ae94,0x4a6a0},
136 {"Super A",0x1,0x376b8,0x56ea0,0x0,0x0,0x376b8,0x56ea0},
137 {"Super B",0x1,0x4a768,0x76e58,0x0,0x0,0x4a768,0x76e58},
138 {"Letter Plus",0x1,0x34b5c,0x4eb16,0x0,0x0,0x34b5c,0x4eb16},
139 {"A4 Plus",0x1,0x33450,0x50910,0x0,0x0,0x33450,0x50910},
140 {"A5 Transverse",0x1,0x24220,0x33450,0x0,0x0,0x24220,0x33450},
141 {"B5 (JIS) Transverse",0x1,0x2c6f0,0x3ebe8,0x0,0x0,0x2c6f0,0x3ebe8},
142 {"A3 Extra",0x1,0x4e9d0,0x6ca48,0x0,0x0,0x4e9d0,0x6ca48},
143 {"A5 Extra",0x1,0x2a7b0,0x395f8,0x0,0x0,0x2a7b0,0x395f8},
144 {"B5 (ISO) Extra",0x1,0x31128,0x43620,0x0,0x0,0x31128,0x43620},
145 {"A2",0x1,0x668a0,0x91050,0x0,0x0,0x668a0,0x91050},
146 {"A3 Transverse",0x1,0x48828,0x668a0,0x0,0x0,0x48828,0x668a0},
147 {"A3 Extra Transverse",0x1,0x4e9d0,0x6ca48,0x0,0x0,0x4e9d0,0x6ca48},
148 {"Japanese Double Postcard",0x1,0x30d40,0x24220,0x0,0x0,0x30d40,0x24220},
149 {"A6",0x1,0x19a28,0x24220,0x0,0x0,0x19a28,0x24220},
150 {"Japanese Envelope Kaku #2",0x1,0x3a980,0x510e0,0x0,0x0,0x3a980,0x510e0},
151 {"Japanese Envelope Kaku #3",0x1,0x34bc0,0x43a08,0x0,0x0,0x34bc0,0x43a08},
152 {"Japanese Envelope Chou #3",0x1,0x1d4c0,0x395f8,0x0,0x0,0x1d4c0,0x395f8},
153 {"Japanese Envelope Chou #4",0x1,0x15f90,0x320c8,0x0,0x0,0x15f90,0x320c8},
154 {"Letter Rotated",0x1,0x44368,0x34b5c,0x0,0x0,0x44368,0x34b5c},
155 {"A3 Rotated",0x1,0x668a0,0x48828,0x0,0x0,0x668a0,0x48828},
156 {"A4 Rotated",0x1,0x48828,0x33450,0x0,0x0,0x48828,0x33450},
157 {"A5 Rotated",0x1,0x33450,0x24220,0x0,0x0,0x33450,0x24220},
158 {"B4 (JIS) Rotated",0x1,0x58de0,0x3ebe8,0x0,0x0,0x58de0,0x3ebe8},
159 {"B5 (JIS) Rotated",0x1,0x3ebe8,0x2c6f0,0x0,0x0,0x3ebe8,0x2c6f0},
160 {"Japanese Postcard Rotated",0x1,0x24220,0x186a0,0x0,0x0,0x24220,0x186a0},
161 {"Double Japan Postcard Rotated",0x1,0x24220,0x30d40,0x0,0x0,0x24220,0x30d40},
162 {"A6 Rotated",0x1,0x24220,0x19a28,0x0,0x0,0x24220,0x19a28},
163 {"Japan Envelope Kaku #2 Rotated",0x1,0x510e0,0x3a980,0x0,0x0,0x510e0,0x3a980},
164 {"Japan Envelope Kaku #3 Rotated",0x1,0x43a08,0x34bc0,0x0,0x0,0x43a08, 0x34bc0},
165 {"Japan Envelope Chou #3 Rotated",0x1,0x395f8,0x1d4c0,0x0,0x0,0x395f8,0x1d4c0},
166 {"Japan Envelope Chou #4 Rotated",0x1,0x320c8,0x15f90,0x0,0x0,0x320c8,0x15f90},
167 {"B6 (JIS)",0x1,0x1f400,0x2c6f0,0x0,0x0,0x1f400,0x2c6f0},
168 {"B6 (JIS) Rotated",0x1,0x2c6f0,0x1f400,0x0,0x0,0x2c6f0,0x1f400},
169 {"12x11",0x1,0x4a724,0x443e1,0x0,0x0,0x4a724,0x443e1},
170 {"Japan Envelope You #4",0x1,0x19a28,0x395f8,0x0,0x0,0x19a28,0x395f8},
171 {"Japan Envelope You #4 Rotated",0x1,0x395f8,0x19a28,0x0,0x0,0x395f8,0x19a28},
172 {"PRC 16K",0x1,0x2de60,0x3f7a0,0x0,0x0,0x2de60,0x3f7a0},
173 {"PRC 32K",0x1,0x1fbd0,0x2cec0,0x0,0x0,0x1fbd0,0x2cec0},
174 {"PRC 32K(Big)",0x1,0x222e0,0x318f8,0x0,0x0,0x222e0,0x318f8},
175 {"PRC Envelope #1",0x1,0x18e70,0x28488,0x0,0x0,0x18e70,0x28488},
176 {"PRC Envelope #2",0x1,0x18e70,0x2af80,0x0,0x0,0x18e70,0x2af80},
177 {"PRC Envelope #3",0x1,0x1e848,0x2af80,0x0,0x0,0x1e848,0x2af80},
178 {"PRC Envelope #4",0x1,0x1adb0,0x32c80,0x0,0x0,0x1adb0,0x32c80},
179 {"PRC Envelope #5",0x1,0x1adb0,0x35b60,0x0,0x0,0x1adb0,0x35b60},
180 {"PRC Envelope #6",0x1,0x1d4c0,0x38270,0x0,0x0,0x1d4c0,0x38270},
181 {"PRC Envelope #7",0x1,0x27100,0x38270,0x0,0x0,0x27100,0x38270},
182 {"PRC Envelope #8",0x1,0x1d4c0,0x4b708,0x0,0x0,0x1d4c0,0x4b708},
183 {"PRC Envelope #9",0x1,0x37e88,0x4f1a0,0x0,0x0,0x37e88,0x4f1a0},
184 {"PRC Envelope #10",0x1,0x4f1a0,0x6fd10,0x0,0x0,0x4f1a0,0x6fd10},
185 {"PRC 16K Rotated",0x1,0x3f7a0,0x2de60,0x0,0x0,0x3f7a0,0x2de60},
186 {"PRC 32K Rotated",0x1,0x2cec0,0x1fbd0,0x0,0x0,0x2cec0,0x1fbd0},
187 {"PRC 32K(Big) Rotated",0x1,0x318f8,0x222e0,0x0,0x0,0x318f8,0x222e0},
188 {"PRC Envelope #1 Rotated",0x1,0x28488,0x18e70,0x0,0x0,0x28488,0x18e70},
189 {"PRC Envelope #2 Rotated",0x1,0x2af80,0x18e70,0x0,0x0,0x2af80,0x18e70},
190 {"PRC Envelope #3 Rotated",0x1,0x2af80,0x1e848,0x0,0x0,0x2af80,0x1e848},
191 {"PRC Envelope #4 Rotated",0x1,0x32c80,0x1adb0,0x0,0x0,0x32c80,0x1adb0},
192 {"PRC Envelope #5 Rotated",0x1,0x35b60,0x1adb0,0x0,0x0,0x35b60,0x1adb0},
193 {"PRC Envelope #6 Rotated",0x1,0x38270,0x1d4c0,0x0,0x0,0x38270,0x1d4c0},
194 {"PRC Envelope #7 Rotated",0x1,0x38270,0x27100,0x0,0x0,0x38270,0x27100},
195 {"PRC Envelope #8 Rotated",0x1,0x4b708,0x1d4c0,0x0,0x0,0x4b708,0x1d4c0},
196 {"PRC Envelope #9 Rotated",0x1,0x4f1a0,0x37e88,0x0,0x0,0x4f1a0,0x37e88},
197 {"PRC Envelope #10 Rotated",0x1,0x6fd10,0x4f1a0,0x0,0x0,0x6fd10,0x4f1a0}
200 static BOOL
upgrade_to_version_3(void)
202 TDB_DATA kbuf
, newkey
, dbuf
;
204 DEBUG(0,("upgrade_to_version_3: upgrading print tdb's to version 3\n"));
206 for (kbuf
= tdb_firstkey(tdb_drivers
); kbuf
.dptr
;
207 newkey
= tdb_nextkey(tdb_drivers
, kbuf
), safe_free(kbuf
.dptr
), kbuf
=newkey
) {
209 dbuf
= tdb_fetch(tdb_drivers
, kbuf
);
211 if (strncmp(kbuf
.dptr
, FORMS_PREFIX
, strlen(FORMS_PREFIX
)) == 0) {
212 DEBUG(0,("upgrade_to_version_3:moving form\n"));
213 if (tdb_store(tdb_forms
, kbuf
, dbuf
, TDB_REPLACE
) != 0) {
214 DEBUG(0,("upgrade_to_version_3: failed to move form. Error (%s).\n", tdb_errorstr(tdb_forms
)));
217 if (tdb_delete(tdb_drivers
, kbuf
) != 0) {
218 DEBUG(0,("upgrade_to_version_3: failed to delete form. Error (%s)\n", tdb_errorstr(tdb_drivers
)));
223 if (strncmp(kbuf
.dptr
, PRINTERS_PREFIX
, strlen(PRINTERS_PREFIX
)) == 0) {
224 DEBUG(0,("upgrade_to_version_3:moving printer\n"));
225 if (tdb_store(tdb_printers
, kbuf
, dbuf
, TDB_REPLACE
) != 0) {
226 DEBUG(0,("upgrade_to_version_3: failed to move printer. Error (%s)\n", tdb_errorstr(tdb_printers
)));
229 if (tdb_delete(tdb_drivers
, kbuf
) != 0) {
230 DEBUG(0,("upgrade_to_version_3: failed to delete printer. Error (%s)\n", tdb_errorstr(tdb_drivers
)));
235 if (strncmp(kbuf
.dptr
, SECDESC_PREFIX
, strlen(SECDESC_PREFIX
)) == 0) {
236 DEBUG(0,("upgrade_to_version_3:moving secdesc\n"));
237 if (tdb_store(tdb_printers
, kbuf
, dbuf
, TDB_REPLACE
) != 0) {
238 DEBUG(0,("upgrade_to_version_3: failed to move secdesc. Error (%s)\n", tdb_errorstr(tdb_printers
)));
241 if (tdb_delete(tdb_drivers
, kbuf
) != 0) {
242 DEBUG(0,("upgrade_to_version_3: failed to delete secdesc. Error (%s)\n", tdb_errorstr(tdb_drivers
)));
247 SAFE_FREE(dbuf
.dptr
);
253 /****************************************************************************
254 Open the NT printing tdb.
255 ****************************************************************************/
257 BOOL
nt_printing_init(void)
259 static pid_t local_pid
;
260 char *vstring
= "INFO/version";
262 if (tdb_drivers
&& tdb_printers
&& tdb_forms
&& local_pid
== sys_getpid())
265 tdb_drivers
= tdb_open_log(lock_path("ntdrivers.tdb"), 0, TDB_DEFAULT
, O_RDWR
|O_CREAT
, 0600);
267 DEBUG(0,("nt_printing_init: Failed to open nt drivers database %s (%s)\n",
268 lock_path("ntdrivers.tdb"), strerror(errno
) ));
272 tdb_printers
= tdb_open_log(lock_path("ntprinters.tdb"), 0, TDB_DEFAULT
, O_RDWR
|O_CREAT
, 0600);
274 DEBUG(0,("nt_printing_init: Failed to open nt printers database %s (%s)\n",
275 lock_path("ntprinters.tdb"), strerror(errno
) ));
279 tdb_forms
= tdb_open_log(lock_path("ntforms.tdb"), 0, TDB_DEFAULT
, O_RDWR
|O_CREAT
, 0600);
281 DEBUG(0,("nt_printing_init: Failed to open nt forms database %s (%s)\n",
282 lock_path("ntforms.tdb"), strerror(errno
) ));
286 local_pid
= sys_getpid();
288 /* handle a Samba upgrade */
289 tdb_lock_bystring(tdb_drivers
, vstring
);
293 /* Cope with byte-reversed older versions of the db. */
294 vers_id
= tdb_fetch_int32(tdb_drivers
, vstring
);
295 if ((vers_id
== NTDRIVERS_DATABASE_VERSION_2
) || (IREV(vers_id
) == NTDRIVERS_DATABASE_VERSION_2
)) {
296 /* Written on a bigendian machine with old fetch_int code. Save as le. */
297 /* The only upgrade between V2 and V3 is to save the version in little-endian. */
298 tdb_store_int32(tdb_drivers
, vstring
, NTDRIVERS_DATABASE_VERSION
);
299 vers_id
= NTDRIVERS_DATABASE_VERSION
;
302 if (vers_id
!= NTDRIVERS_DATABASE_VERSION
) {
304 if ((vers_id
== NTDRIVERS_DATABASE_VERSION_1
) || (IREV(vers_id
) == NTDRIVERS_DATABASE_VERSION_1
)) {
305 if (!upgrade_to_version_3())
308 tdb_traverse(tdb_drivers
, tdb_traverse_delete_fn
, NULL
);
310 tdb_store_int32(tdb_drivers
, vstring
, NTDRIVERS_DATABASE_VERSION
);
313 tdb_unlock_bystring(tdb_drivers
, vstring
);
315 update_c_setprinter(True
);
318 * register callback to handle updating printers as new
319 * drivers are installed
321 message_register(MSG_PRINTER_DRVUPGRADE
, do_drv_upgrade_printer
);
325 /*******************************************************************
326 tdb traversal function for counting printers.
327 ********************************************************************/
329 static int traverse_counting_printers(TDB_CONTEXT
*t
, TDB_DATA key
,
330 TDB_DATA data
, void *context
)
332 int *printer_count
= (int*)context
;
334 if (memcmp(PRINTERS_PREFIX
, key
.dptr
, sizeof(PRINTERS_PREFIX
)-1) == 0) {
336 DEBUG(10,("traverse_counting_printers: printer = [%s] printer_count = %d\n", key
.dptr
, *printer_count
));
342 /*******************************************************************
343 Update the spooler global c_setprinter. This variable is initialized
344 when the parent smbd starts with the number of existing printers. It
345 is monotonically increased by the current number of printers *after*
346 each add or delete printer RPC. Only Microsoft knows why... JRR020119
347 ********************************************************************/
349 uint32
update_c_setprinter(BOOL initialize
)
352 int32 printer_count
= 0;
354 tdb_lock_bystring(tdb_printers
, GLOBAL_C_SETPRINTER
);
356 /* Traverse the tdb, counting the printers */
357 tdb_traverse(tdb_printers
, traverse_counting_printers
, (void *)&printer_count
);
359 /* If initializing, set c_setprinter to current printers count
360 * otherwise, bump it by the current printer count
363 c_setprinter
= tdb_fetch_int32(tdb_printers
, GLOBAL_C_SETPRINTER
) + printer_count
;
365 c_setprinter
= printer_count
;
367 DEBUG(10,("update_c_setprinter: c_setprinter = %u\n", (unsigned int)c_setprinter
));
368 tdb_store_int32(tdb_printers
, GLOBAL_C_SETPRINTER
, c_setprinter
);
370 tdb_unlock_bystring(tdb_printers
, GLOBAL_C_SETPRINTER
);
372 return (uint32
)c_setprinter
;
375 /*******************************************************************
376 Get the spooler global c_setprinter, accounting for initialization.
377 ********************************************************************/
379 uint32
get_c_setprinter(void)
381 int32 c_setprinter
= tdb_fetch_int32(tdb_printers
, GLOBAL_C_SETPRINTER
);
383 if (c_setprinter
== (int32
)-1)
384 c_setprinter
= update_c_setprinter(True
);
386 DEBUG(10,("get_c_setprinter: c_setprinter = %d\n", c_setprinter
));
388 return (uint32
)c_setprinter
;
391 /****************************************************************************
392 Get builtin form struct list.
393 ****************************************************************************/
395 int get_builtin_ntforms(nt_forms_struct
**list
)
397 *list
= (nt_forms_struct
*)memdup(&default_forms
[0], sizeof(default_forms
));
398 return sizeof(default_forms
) / sizeof(default_forms
[0]);
401 /****************************************************************************
402 get a builtin form struct
403 ****************************************************************************/
405 BOOL
get_a_builtin_ntform(UNISTR2
*uni_formname
,nt_forms_struct
*form
)
409 unistr2_to_ascii(form_name
, uni_formname
, sizeof(form_name
)-1);
410 DEBUGADD(6,("Looking for builtin form %s \n", form_name
));
411 count
= sizeof(default_forms
) / sizeof(default_forms
[0]);
412 for (i
=0;i
<count
;i
++) {
413 if (strequal(form_name
,default_forms
[i
].name
)) {
414 DEBUGADD(6,("Found builtin form %s \n", form_name
));
415 memcpy(form
,&default_forms
[i
],sizeof(*form
));
423 /****************************************************************************
424 get a form struct list
425 ****************************************************************************/
426 int get_ntforms(nt_forms_struct
**list
)
428 TDB_DATA kbuf
, newkey
, dbuf
;
430 nt_forms_struct form
;
435 for (kbuf
= tdb_firstkey(tdb_forms
);
437 newkey
= tdb_nextkey(tdb_forms
, kbuf
), safe_free(kbuf
.dptr
), kbuf
=newkey
) {
438 if (strncmp(kbuf
.dptr
, FORMS_PREFIX
, strlen(FORMS_PREFIX
)) != 0) continue;
440 dbuf
= tdb_fetch(tdb_forms
, kbuf
);
441 if (!dbuf
.dptr
) continue;
443 fstrcpy(form
.name
, kbuf
.dptr
+strlen(FORMS_PREFIX
));
444 ret
= tdb_unpack(dbuf
.dptr
, dbuf
.dsize
, "dddddddd",
445 &i
, &form
.flag
, &form
.width
, &form
.length
, &form
.left
,
446 &form
.top
, &form
.right
, &form
.bottom
);
447 SAFE_FREE(dbuf
.dptr
);
448 if (ret
!= dbuf
.dsize
) continue;
450 tl
= Realloc(*list
, sizeof(nt_forms_struct
)*(n
+1));
452 DEBUG(0,("get_ntforms: Realloc fail.\n"));
464 /****************************************************************************
465 write a form struct list
466 ****************************************************************************/
467 int write_ntforms(nt_forms_struct
**list
, int number
)
474 for (i
=0;i
<number
;i
++) {
475 /* save index, so list is rebuilt in correct order */
476 len
= tdb_pack(buf
, sizeof(buf
), "dddddddd",
477 i
, (*list
)[i
].flag
, (*list
)[i
].width
, (*list
)[i
].length
,
478 (*list
)[i
].left
, (*list
)[i
].top
, (*list
)[i
].right
,
480 if (len
> sizeof(buf
)) break;
481 slprintf(key
, sizeof(key
)-1, "%s%s", FORMS_PREFIX
, (*list
)[i
].name
);
482 kbuf
.dsize
= strlen(key
)+1;
486 if (tdb_store(tdb_forms
, kbuf
, dbuf
, TDB_REPLACE
) != 0) break;
492 /****************************************************************************
493 add a form struct at the end of the list
494 ****************************************************************************/
495 BOOL
add_a_form(nt_forms_struct
**list
, const FORM
*form
, int *count
)
503 * NT tries to add forms even when
504 * they are already in the base
505 * only update the values if already present
510 unistr2_to_ascii(form_name
, &form
->name
, sizeof(form_name
)-1);
511 for (n
=0; n
<*count
; n
++) {
512 if (!strncmp((*list
)[n
].name
, form_name
, strlen(form_name
))) {
513 DEBUG(103, ("NT workaround, [%s] already exists\n", form_name
));
520 if((tl
=Realloc(*list
, (n
+1)*sizeof(nt_forms_struct
))) == NULL
) {
521 DEBUG(0,("add_a_form: failed to enlarge forms list!\n"));
525 unistr2_to_ascii((*list
)[n
].name
, &form
->name
, sizeof((*list
)[n
].name
)-1);
529 (*list
)[n
].flag
=form
->flags
;
530 (*list
)[n
].width
=form
->size_x
;
531 (*list
)[n
].length
=form
->size_y
;
532 (*list
)[n
].left
=form
->left
;
533 (*list
)[n
].top
=form
->top
;
534 (*list
)[n
].right
=form
->right
;
535 (*list
)[n
].bottom
=form
->bottom
;
540 /****************************************************************************
541 delete a named form struct
542 ****************************************************************************/
543 BOOL
delete_a_form(nt_forms_struct
**list
, UNISTR2
*del_name
, int *count
, WERROR
*ret
)
552 unistr2_to_ascii(form_name
, del_name
, sizeof(form_name
)-1);
554 for (n
=0; n
<*count
; n
++) {
555 if (!strncmp((*list
)[n
].name
, form_name
, strlen(form_name
))) {
556 DEBUG(103, ("delete_a_form, [%s] in list\n", form_name
));
562 DEBUG(10,("delete_a_form, [%s] not found\n", form_name
));
563 *ret
= WERR_INVALID_PARAM
;
567 slprintf(key
, sizeof(key
)-1, "%s%s", FORMS_PREFIX
, (*list
)[n
].name
);
568 kbuf
.dsize
= strlen(key
)+1;
570 if (tdb_delete(tdb_forms
, kbuf
) != 0) {
578 /****************************************************************************
580 ****************************************************************************/
581 void update_a_form(nt_forms_struct
**list
, const FORM
*form
, int count
)
585 unistr2_to_ascii(form_name
, &(form
->name
), sizeof(form_name
)-1);
587 DEBUG(106, ("[%s]\n", form_name
));
588 for (n
=0; n
<count
; n
++)
590 DEBUGADD(106, ("n [%d]:[%s]\n", n
, (*list
)[n
].name
));
591 if (!strncmp((*list
)[n
].name
, form_name
, strlen(form_name
)))
595 if (n
==count
) return;
597 (*list
)[n
].flag
=form
->flags
;
598 (*list
)[n
].width
=form
->size_x
;
599 (*list
)[n
].length
=form
->size_y
;
600 (*list
)[n
].left
=form
->left
;
601 (*list
)[n
].top
=form
->top
;
602 (*list
)[n
].right
=form
->right
;
603 (*list
)[n
].bottom
=form
->bottom
;
606 /****************************************************************************
607 get the nt drivers list
609 traverse the database and look-up the matching names
610 ****************************************************************************/
611 int get_ntdrivers(fstring
**list
, char *architecture
, uint32 version
)
617 TDB_DATA kbuf
, newkey
;
619 get_short_archi(short_archi
, architecture
);
620 slprintf(key
, sizeof(key
)-1, "%s%s/%d/", DRIVERS_PREFIX
, short_archi
, version
);
622 for (kbuf
= tdb_firstkey(tdb_drivers
);
624 newkey
= tdb_nextkey(tdb_drivers
, kbuf
), safe_free(kbuf
.dptr
), kbuf
=newkey
) {
625 if (strncmp(kbuf
.dptr
, key
, strlen(key
)) != 0) continue;
627 if((fl
= Realloc(*list
, sizeof(fstring
)*(total
+1))) == NULL
) {
628 DEBUG(0,("get_ntdrivers: failed to enlarge list!\n"));
633 fstrcpy((*list
)[total
], kbuf
.dptr
+strlen(key
));
640 /****************************************************************************
641 function to do the mapping between the long architecture name and
643 ****************************************************************************/
644 BOOL
get_short_archi(char *short_archi
, char *long_archi
)
651 struct table archi_table
[]=
653 {"Windows 4.0", "WIN40" },
654 {"Windows NT x86", "W32X86" },
655 {"Windows NT R4000", "W32MIPS" },
656 {"Windows NT Alpha_AXP", "W32ALPHA" },
657 {"Windows NT PowerPC", "W32PPC" },
663 DEBUG(107,("Getting architecture dependant directory\n"));
666 } while ( (archi_table
[i
].long_archi
!=NULL
) &&
667 StrCaseCmp(long_archi
, archi_table
[i
].long_archi
) );
669 if (archi_table
[i
].long_archi
==NULL
) {
670 DEBUGADD(107,("Unknown architecture [%s] !\n", long_archi
));
674 StrnCpy (short_archi
, archi_table
[i
].short_archi
, strlen(archi_table
[i
].short_archi
));
676 DEBUGADD(108,("index: [%d]\n", i
));
677 DEBUGADD(108,("long architecture: [%s]\n", long_archi
));
678 DEBUGADD(108,("short architecture: [%s]\n", short_archi
));
683 /****************************************************************************
684 Version information in Microsoft files is held in a VS_VERSION_INFO structure.
685 There are two case to be covered here: PE (Portable Executable) and NE (New
686 Executable) files. Both files support the same INFO structure, but PE files
687 store the signature in unicode, and NE files store it as !unicode.
688 returns -1 on error, 1 on version info found, and 0 on no version info found.
689 ****************************************************************************/
691 static int get_file_version(files_struct
*fsp
, char *fname
,uint32
*major
, uint32
*minor
)
697 if ((buf
=malloc(PE_HEADER_SIZE
)) == NULL
) {
698 DEBUG(0,("get_file_version: PE file [%s] PE Header malloc failed bytes = %d\n",
699 fname
, PE_HEADER_SIZE
));
703 /* Note: DOS_HEADER_SIZE < malloc'ed PE_HEADER_SIZE */
704 if ((byte_count
= vfs_read_data(fsp
, buf
, DOS_HEADER_SIZE
)) < DOS_HEADER_SIZE
) {
705 DEBUG(3,("get_file_version: File [%s] DOS header too short, bytes read = %d\n",
707 goto no_version_info
;
710 /* Is this really a DOS header? */
711 if (SVAL(buf
,DOS_HEADER_MAGIC_OFFSET
) != DOS_HEADER_MAGIC
) {
712 DEBUG(6,("get_file_version: File [%s] bad DOS magic = 0x%x\n",
713 fname
, SVAL(buf
,DOS_HEADER_MAGIC_OFFSET
)));
714 goto no_version_info
;
717 /* Skip OEM header (if any) and the DOS stub to start of Windows header */
718 if (fsp
->conn
->vfs_ops
.lseek(fsp
, fsp
->fd
, SVAL(buf
,DOS_HEADER_LFANEW_OFFSET
), SEEK_SET
) == (SMB_OFF_T
)-1) {
719 DEBUG(3,("get_file_version: File [%s] too short, errno = %d\n",
721 /* Assume this isn't an error... the file just looks sort of like a PE/NE file */
722 goto no_version_info
;
725 if ((byte_count
= vfs_read_data(fsp
, buf
, PE_HEADER_SIZE
)) < PE_HEADER_SIZE
) {
726 DEBUG(3,("get_file_version: File [%s] Windows header too short, bytes read = %d\n",
728 /* Assume this isn't an error... the file just looks sort of like a PE/NE file */
729 goto no_version_info
;
732 /* The header may be a PE (Portable Executable) or an NE (New Executable) */
733 if (IVAL(buf
,PE_HEADER_SIGNATURE_OFFSET
) == PE_HEADER_SIGNATURE
) {
735 int section_table_bytes
;
737 if (SVAL(buf
,PE_HEADER_MACHINE_OFFSET
) != PE_HEADER_MACHINE_I386
) {
738 DEBUG(3,("get_file_version: PE file [%s] wrong machine = 0x%x\n",
739 fname
, SVAL(buf
,PE_HEADER_MACHINE_OFFSET
)));
740 /* At this point, we assume the file is in error. It still could be somthing
741 * else besides a PE file, but it unlikely at this point.
746 /* get the section table */
747 num_sections
= SVAL(buf
,PE_HEADER_NUMBER_OF_SECTIONS
);
748 section_table_bytes
= num_sections
* PE_HEADER_SECT_HEADER_SIZE
;
750 if ((buf
=malloc(section_table_bytes
)) == NULL
) {
751 DEBUG(0,("get_file_version: PE file [%s] section table malloc failed bytes = %d\n",
752 fname
, section_table_bytes
));
756 if ((byte_count
= vfs_read_data(fsp
, buf
, section_table_bytes
)) < section_table_bytes
) {
757 DEBUG(3,("get_file_version: PE file [%s] Section header too short, bytes read = %d\n",
762 /* Iterate the section table looking for the resource section ".rsrc" */
763 for (i
= 0; i
< num_sections
; i
++) {
764 int sec_offset
= i
* PE_HEADER_SECT_HEADER_SIZE
;
766 if (strcmp(".rsrc", &buf
[sec_offset
+PE_HEADER_SECT_NAME_OFFSET
]) == 0) {
767 int section_pos
= IVAL(buf
,sec_offset
+PE_HEADER_SECT_PTR_DATA_OFFSET
);
768 int section_bytes
= IVAL(buf
,sec_offset
+PE_HEADER_SECT_SIZE_DATA_OFFSET
);
771 if ((buf
=malloc(section_bytes
)) == NULL
) {
772 DEBUG(0,("get_file_version: PE file [%s] version malloc failed bytes = %d\n",
773 fname
, section_bytes
));
777 /* Seek to the start of the .rsrc section info */
778 if (fsp
->conn
->vfs_ops
.lseek(fsp
, fsp
->fd
, section_pos
, SEEK_SET
) == (SMB_OFF_T
)-1) {
779 DEBUG(3,("get_file_version: PE file [%s] too short for section info, errno = %d\n",
784 if ((byte_count
= vfs_read_data(fsp
, buf
, section_bytes
)) < section_bytes
) {
785 DEBUG(3,("get_file_version: PE file [%s] .rsrc section too short, bytes read = %d\n",
790 for (i
=0; i
<section_bytes
-VS_VERSION_INFO_UNICODE_SIZE
; i
++) {
791 /* Scan for 1st 3 unicoded bytes followed by word aligned magic value */
792 if (buf
[i
] == 'V' && buf
[i
+1] == '\0' && buf
[i
+2] == 'S') {
793 /* Align to next long address */
794 int pos
= (i
+ sizeof(VS_SIGNATURE
)*2 + 3) & 0xfffffffc;
796 if (IVAL(buf
,pos
) == VS_MAGIC_VALUE
) {
797 *major
= IVAL(buf
,pos
+VS_MAJOR_OFFSET
);
798 *minor
= IVAL(buf
,pos
+VS_MINOR_OFFSET
);
800 DEBUG(6,("get_file_version: PE file [%s] Version = %08x:%08x (%d.%d.%d.%d)\n",
801 fname
, *major
, *minor
,
802 (*major
>>16)&0xffff, *major
&0xffff,
803 (*minor
>>16)&0xffff, *minor
&0xffff));
812 /* Version info not found, fall back to origin date/time */
813 DEBUG(10,("get_file_version: PE file [%s] has no version info\n", fname
));
817 } else if (SVAL(buf
,NE_HEADER_SIGNATURE_OFFSET
) == NE_HEADER_SIGNATURE
) {
818 if (CVAL(buf
,NE_HEADER_TARGET_OS_OFFSET
) != NE_HEADER_TARGOS_WIN
) {
819 DEBUG(3,("get_file_version: NE file [%s] wrong target OS = 0x%x\n",
820 fname
, CVAL(buf
,NE_HEADER_TARGET_OS_OFFSET
)));
821 /* At this point, we assume the file is in error. It still could be somthing
822 * else besides a NE file, but it unlikely at this point. */
826 /* Allocate a bit more space to speed up things */
828 if ((buf
=malloc(VS_NE_BUF_SIZE
)) == NULL
) {
829 DEBUG(0,("get_file_version: NE file [%s] malloc failed bytes = %d\n",
830 fname
, PE_HEADER_SIZE
));
834 /* This is a HACK! I got tired of trying to sort through the messy
835 * 'NE' file format. If anyone wants to clean this up please have at
836 * it, but this works. 'NE' files will eventually fade away. JRR */
837 while((byte_count
= vfs_read_data(fsp
, buf
, VS_NE_BUF_SIZE
)) > 0) {
838 /* Cover case that should not occur in a well formed 'NE' .dll file */
839 if (byte_count
-VS_VERSION_INFO_SIZE
<= 0) break;
841 for(i
=0; i
<byte_count
; i
++) {
842 /* Fast skip past data that can't possibly match */
843 if (buf
[i
] != 'V') continue;
845 /* Potential match data crosses buf boundry, move it to beginning
846 * of buf, and fill the buf with as much as it will hold. */
847 if (i
>byte_count
-VS_VERSION_INFO_SIZE
) {
850 memcpy(buf
, &buf
[i
], byte_count
-i
);
851 if ((bc
= vfs_read_data(fsp
, &buf
[byte_count
-i
], VS_NE_BUF_SIZE
-
852 (byte_count
-i
))) < 0) {
854 DEBUG(0,("get_file_version: NE file [%s] Read error, errno=%d\n",
859 byte_count
= bc
+ (byte_count
- i
);
860 if (byte_count
<VS_VERSION_INFO_SIZE
) break;
865 /* Check that the full signature string and the magic number that
866 * follows exist (not a perfect solution, but the chances that this
867 * occurs in code is, well, remote. Yes I know I'm comparing the 'V'
868 * twice, as it is simpler to read the code. */
869 if (strcmp(&buf
[i
], VS_SIGNATURE
) == 0) {
870 /* Compute skip alignment to next long address */
871 int skip
= -(fsp
->conn
->vfs_ops
.lseek(fsp
, fsp
->fd
, 0, SEEK_CUR
) - (byte_count
- i
) +
872 sizeof(VS_SIGNATURE
)) & 3;
873 if (IVAL(buf
,i
+sizeof(VS_SIGNATURE
)+skip
) != 0xfeef04bd) continue;
875 *major
= IVAL(buf
,i
+sizeof(VS_SIGNATURE
)+skip
+VS_MAJOR_OFFSET
);
876 *minor
= IVAL(buf
,i
+sizeof(VS_SIGNATURE
)+skip
+VS_MINOR_OFFSET
);
877 DEBUG(6,("get_file_version: NE file [%s] Version = %08x:%08x (%d.%d.%d.%d)\n",
878 fname
, *major
, *minor
,
879 (*major
>>16)&0xffff, *major
&0xffff,
880 (*minor
>>16)&0xffff, *minor
&0xffff));
887 /* Version info not found, fall back to origin date/time */
888 DEBUG(0,("get_file_version: NE file [%s] Version info not found\n", fname
));
893 /* Assume this isn't an error... the file just looks sort of like a PE/NE file */
894 DEBUG(3,("get_file_version: File [%s] unknown file format, signature = 0x%x\n",
895 fname
, IVAL(buf
,PE_HEADER_SIGNATURE_OFFSET
)));
906 /****************************************************************************
907 Drivers for Microsoft systems contain multiple files. Often, multiple drivers
908 share one or more files. During the MS installation process files are checked
909 to insure that only a newer version of a shared file is installed over an
910 older version. There are several possibilities for this comparison. If there
911 is no previous version, the new one is newer (obviously). If either file is
912 missing the version info structure, compare the creation date (on Unix use
913 the modification date). Otherwise chose the numerically larger version number.
914 ****************************************************************************/
915 static int file_version_is_newer(connection_struct
*conn
, fstring new_file
,
918 BOOL use_version
= True
;
923 time_t new_create_time
;
927 time_t old_create_time
;
931 files_struct
*fsp
= NULL
;
933 SMB_STRUCT_STAT stat_buf
;
937 ZERO_STRUCT(stat_buf
);
938 new_create_time
= (time_t)0;
939 old_create_time
= (time_t)0;
941 /* Get file version info (if available) for previous file (if it exists) */
942 pstrcpy(filepath
, old_file
);
944 unix_convert(filepath
,conn
,NULL
,&bad_path
,&stat_buf
);
946 fsp
= open_file_shared(conn
, filepath
, &stat_buf
,
947 SET_OPEN_MODE(DOS_OPEN_RDONLY
),
948 (FILE_FAIL_IF_NOT_EXIST
|FILE_EXISTS_OPEN
),
949 0, 0, &access_mode
, &action
);
951 /* Old file not found, so by definition new file is in fact newer */
952 DEBUG(10,("file_version_is_newer: Can't open old file [%s], errno = %d\n",
957 int ret
= get_file_version(fsp
, old_file
, &old_major
, &old_minor
);
958 if (ret
== -1) goto error_exit
;
961 DEBUG(6,("file_version_is_newer: Version info not found [%s], use mod time\n",
964 if (fsp
->conn
->vfs_ops
.fstat(fsp
, fsp
->fd
, &st
) == -1) goto error_exit
;
965 old_create_time
= st
.st_mtime
;
966 DEBUGADD(6,("file_version_is_newer: mod time = %ld sec\n", old_create_time
));
969 close_file(fsp
, True
);
971 /* Get file version info (if available) for new file */
972 pstrcpy(filepath
, new_file
);
973 unix_convert(filepath
,conn
,NULL
,&bad_path
,&stat_buf
);
975 fsp
= open_file_shared(conn
, filepath
, &stat_buf
,
976 SET_OPEN_MODE(DOS_OPEN_RDONLY
),
977 (FILE_FAIL_IF_NOT_EXIST
|FILE_EXISTS_OPEN
),
978 0, 0, &access_mode
, &action
);
980 /* New file not found, this shouldn't occur if the caller did its job */
981 DEBUG(3,("file_version_is_newer: Can't open new file [%s], errno = %d\n",
986 int ret
= get_file_version(fsp
, new_file
, &new_major
, &new_minor
);
987 if (ret
== -1) goto error_exit
;
990 DEBUG(6,("file_version_is_newer: Version info not found [%s], use mod time\n",
993 if (fsp
->conn
->vfs_ops
.fstat(fsp
, fsp
->fd
, &st
) == -1) goto error_exit
;
994 new_create_time
= st
.st_mtime
;
995 DEBUGADD(6,("file_version_is_newer: mod time = %ld sec\n", new_create_time
));
998 close_file(fsp
, True
);
1001 /* Compare versions and choose the larger version number */
1002 if (new_major
> old_major
||
1003 (new_major
== old_major
&& new_minor
> old_minor
)) {
1005 DEBUG(6,("file_version_is_newer: Replacing [%s] with [%s]\n", old_file
, new_file
));
1009 DEBUG(6,("file_version_is_newer: Leaving [%s] unchanged\n", old_file
));
1014 /* Compare modification time/dates and choose the newest time/date */
1015 if (new_create_time
> old_create_time
) {
1016 DEBUG(6,("file_version_is_newer: Replacing [%s] with [%s]\n", old_file
, new_file
));
1020 DEBUG(6,("file_version_is_newer: Leaving [%s] unchanged\n", old_file
));
1027 close_file(fsp
, True
);
1031 /****************************************************************************
1032 Determine the correct cVersion associated with an architecture and driver
1033 ****************************************************************************/
1034 static uint32
get_correct_cversion(fstring architecture
, fstring driverpath_in
,
1035 struct current_user
*user
, WERROR
*perr
)
1043 files_struct
*fsp
= NULL
;
1046 connection_struct
*conn
;
1050 *perr
= WERR_INVALID_PARAM
;
1052 /* If architecture is Windows 95/98/ME, the version is always 0. */
1053 if (strcmp(architecture
, "WIN40") == 0) {
1054 DEBUG(10,("get_correct_cversion: Driver is Win9x, cversion = 0\n"));
1060 * Connect to the print$ share under the same account as the user connected
1061 * to the rpc pipe. Note we must still be root to do this.
1064 /* Null password is ok - we are already an authenticated user... */
1065 null_pw
= data_blob(NULL
, 0);
1067 conn
= make_connection_with_chdir("print$", null_pw
, "A:", user
->vuid
, &nt_status
);
1071 DEBUG(0,("get_correct_cversion: Unable to connect\n"));
1072 *perr
= ntstatus_to_werror(nt_status
);
1076 /* We are temporarily becoming the connection user. */
1077 if (!become_user(conn
, conn
->vuid
)) {
1078 DEBUG(0,("get_correct_cversion: Can't become user!\n"));
1079 *perr
= WERR_ACCESS_DENIED
;
1083 /* Open the driver file (Portable Executable format) and determine the
1084 * deriver the cversion. */
1085 slprintf(driverpath
, sizeof(driverpath
)-1, "%s/%s", architecture
, driverpath_in
);
1087 unix_convert(driverpath
,conn
,NULL
,&bad_path
,&st
);
1089 fsp
= open_file_shared(conn
, driverpath
, &st
,
1090 SET_OPEN_MODE(DOS_OPEN_RDONLY
),
1091 (FILE_FAIL_IF_NOT_EXIST
|FILE_EXISTS_OPEN
),
1092 0, 0, &access_mode
, &action
);
1094 DEBUG(3,("get_correct_cversion: Can't open file [%s], errno = %d\n",
1095 driverpath
, errno
));
1096 *perr
= WERR_ACCESS_DENIED
;
1102 int ret
= get_file_version(fsp
, driverpath
, &major
, &minor
);
1103 if (ret
== -1) goto error_exit
;
1106 DEBUG(6,("get_correct_cversion: Version info not found [%s]\n", driverpath
));
1111 * This is a Microsoft'ism. See references in MSDN to VER_FILEVERSION
1112 * for more details. Version in this case is not just the version of the
1113 * file, but the version in the sense of kernal mode (2) vs. user mode
1114 * (3) drivers. Other bits of the version fields are the version info.
1117 cversion
= major
& 0x0000ffff;
1119 case 2: /* WinNT drivers */
1120 case 3: /* Win2K drivers */
1124 DEBUG(6,("get_correct_cversion: cversion invalid [%s] cversion = %d\n",
1125 driverpath
, cversion
));
1129 DEBUG(10,("get_correct_cversion: Version info found [%s] major = 0x%x minor = 0x%x\n",
1130 driverpath
, major
, minor
));
1133 DEBUG(10,("get_correct_cversion: Driver file [%s] cversion = %d\n",
1134 driverpath
, cversion
));
1136 close_file(fsp
, True
);
1137 close_cnum(conn
, user
->vuid
);
1146 close_file(fsp
, True
);
1148 close_cnum(conn
, user
->vuid
);
1153 /****************************************************************************
1154 ****************************************************************************/
1155 static WERROR
clean_up_driver_struct_level_3(NT_PRINTER_DRIVER_INFO_LEVEL_3
*driver
,
1156 struct current_user
*user
)
1158 fstring architecture
;
1164 /* clean up the driver name.
1165 * we can get .\driver.dll
1166 * or worse c:\windows\system\driver.dll !
1168 /* using an intermediate string to not have overlaping memcpy()'s */
1169 if ((p
= strrchr(driver
->driverpath
,'\\')) != NULL
) {
1170 fstrcpy(new_name
, p
+1);
1171 fstrcpy(driver
->driverpath
, new_name
);
1174 if ((p
= strrchr(driver
->datafile
,'\\')) != NULL
) {
1175 fstrcpy(new_name
, p
+1);
1176 fstrcpy(driver
->datafile
, new_name
);
1179 if ((p
= strrchr(driver
->configfile
,'\\')) != NULL
) {
1180 fstrcpy(new_name
, p
+1);
1181 fstrcpy(driver
->configfile
, new_name
);
1184 if ((p
= strrchr(driver
->helpfile
,'\\')) != NULL
) {
1185 fstrcpy(new_name
, p
+1);
1186 fstrcpy(driver
->helpfile
, new_name
);
1189 if (driver
->dependentfiles
) {
1190 for (i
=0; *driver
->dependentfiles
[i
]; i
++) {
1191 if ((p
= strrchr(driver
->dependentfiles
[i
],'\\')) != NULL
) {
1192 fstrcpy(new_name
, p
+1);
1193 fstrcpy(driver
->dependentfiles
[i
], new_name
);
1198 get_short_archi(architecture
, driver
->environment
);
1200 /* jfm:7/16/2000 the client always sends the cversion=0.
1201 * The server should check which version the driver is by reading
1202 * the PE header of driver->driverpath.
1204 * For Windows 95/98 the version is 0 (so the value sent is correct)
1205 * For Windows NT (the architecture doesn't matter)
1206 * NT 3.1: cversion=0
1207 * NT 3.5/3.51: cversion=1
1211 if ((driver
->cversion
= get_correct_cversion( architecture
,
1212 driver
->driverpath
, user
, &err
)) == -1)
1218 /****************************************************************************
1219 ****************************************************************************/
1220 static WERROR
clean_up_driver_struct_level_6(NT_PRINTER_DRIVER_INFO_LEVEL_6
*driver
,
1221 struct current_user
*user
)
1223 fstring architecture
;
1229 /* clean up the driver name.
1230 * we can get .\driver.dll
1231 * or worse c:\windows\system\driver.dll !
1233 /* using an intermediate string to not have overlaping memcpy()'s */
1234 if ((p
= strrchr(driver
->driverpath
,'\\')) != NULL
) {
1235 fstrcpy(new_name
, p
+1);
1236 fstrcpy(driver
->driverpath
, new_name
);
1239 if ((p
= strrchr(driver
->datafile
,'\\')) != NULL
) {
1240 fstrcpy(new_name
, p
+1);
1241 fstrcpy(driver
->datafile
, new_name
);
1244 if ((p
= strrchr(driver
->configfile
,'\\')) != NULL
) {
1245 fstrcpy(new_name
, p
+1);
1246 fstrcpy(driver
->configfile
, new_name
);
1249 if ((p
= strrchr(driver
->helpfile
,'\\')) != NULL
) {
1250 fstrcpy(new_name
, p
+1);
1251 fstrcpy(driver
->helpfile
, new_name
);
1254 if (driver
->dependentfiles
) {
1255 for (i
=0; *driver
->dependentfiles
[i
]; i
++) {
1256 if ((p
= strrchr(driver
->dependentfiles
[i
],'\\')) != NULL
) {
1257 fstrcpy(new_name
, p
+1);
1258 fstrcpy(driver
->dependentfiles
[i
], new_name
);
1263 get_short_archi(architecture
, driver
->environment
);
1265 /* jfm:7/16/2000 the client always sends the cversion=0.
1266 * The server should check which version the driver is by reading
1267 * the PE header of driver->driverpath.
1269 * For Windows 95/98 the version is 0 (so the value sent is correct)
1270 * For Windows NT (the architecture doesn't matter)
1271 * NT 3.1: cversion=0
1272 * NT 3.5/3.51: cversion=1
1276 if ((driver
->version
= get_correct_cversion(architecture
,
1277 driver
->driverpath
, user
, &err
)) == -1)
1283 /****************************************************************************
1284 ****************************************************************************/
1285 WERROR
clean_up_driver_struct(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract
,
1286 uint32 level
, struct current_user
*user
)
1291 NT_PRINTER_DRIVER_INFO_LEVEL_3
*driver
;
1292 driver
=driver_abstract
.info_3
;
1293 return clean_up_driver_struct_level_3(driver
, user
);
1297 NT_PRINTER_DRIVER_INFO_LEVEL_6
*driver
;
1298 driver
=driver_abstract
.info_6
;
1299 return clean_up_driver_struct_level_6(driver
, user
);
1302 return WERR_INVALID_PARAM
;
1306 /****************************************************************************
1307 This function sucks and should be replaced. JRA.
1308 ****************************************************************************/
1310 static void convert_level_6_to_level3(NT_PRINTER_DRIVER_INFO_LEVEL_3
*dst
, NT_PRINTER_DRIVER_INFO_LEVEL_6
*src
)
1312 dst
->cversion
= src
->version
;
1314 fstrcpy( dst
->name
, src
->name
);
1315 fstrcpy( dst
->environment
, src
->environment
);
1316 fstrcpy( dst
->driverpath
, src
->driverpath
);
1317 fstrcpy( dst
->datafile
, src
->datafile
);
1318 fstrcpy( dst
->configfile
, src
->configfile
);
1319 fstrcpy( dst
->helpfile
, src
->helpfile
);
1320 fstrcpy( dst
->monitorname
, src
->monitorname
);
1321 fstrcpy( dst
->defaultdatatype
, src
->defaultdatatype
);
1322 dst
->dependentfiles
= src
->dependentfiles
;
1325 #if 0 /* Debugging function */
1327 static char* ffmt(unsigned char *c
){
1329 static char ffmt_str
[17];
1331 for (i
=0; i
<16; i
++) {
1332 if ((c
[i
] < ' ') || (c
[i
] > '~'))
1343 /****************************************************************************
1344 ****************************************************************************/
1345 BOOL
move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract
, uint32 level
,
1346 struct current_user
*user
, WERROR
*perr
)
1348 NT_PRINTER_DRIVER_INFO_LEVEL_3
*driver
;
1349 NT_PRINTER_DRIVER_INFO_LEVEL_3 converted_driver
;
1350 fstring architecture
;
1355 connection_struct
*conn
;
1362 memset(inbuf
, '\0', sizeof(inbuf
));
1363 memset(outbuf
, '\0', sizeof(outbuf
));
1367 driver
=driver_abstract
.info_3
;
1368 else if (level
==6) {
1369 convert_level_6_to_level3(&converted_driver
, driver_abstract
.info_6
);
1370 driver
= &converted_driver
;
1372 DEBUG(0,("move_driver_to_download_area: Unknown info level (%u)\n", (unsigned int)level
));
1376 get_short_archi(architecture
, driver
->environment
);
1379 * Connect to the print$ share under the same account as the user connected to the rpc pipe.
1380 * Note we must be root to do this.
1384 null_pw
= data_blob(NULL
, 0);
1385 conn
= make_connection_with_chdir("print$", null_pw
, "A:", user
->vuid
, &nt_status
);
1389 DEBUG(0,("move_driver_to_download_area: Unable to connect\n"));
1390 *perr
= ntstatus_to_werror(nt_status
);
1395 * Save who we are - we are temporarily becoming the connection user.
1398 if (!become_user(conn
, conn
->vuid
)) {
1399 DEBUG(0,("move_driver_to_download_area: Can't become user!\n"));
1404 * make the directories version and version\driver_name
1405 * under the architecture directory.
1407 DEBUG(5,("Creating first directory\n"));
1408 slprintf(new_dir
, sizeof(new_dir
)-1, "%s/%d", architecture
, driver
->cversion
);
1409 mkdir_internal(conn
, new_dir
);
1411 /* For each driver file, archi\filexxx.yyy, if there is a duplicate file
1412 * listed for this driver which has already been moved, skip it (note:
1413 * drivers may list the same file name several times. Then check if the
1414 * file already exists in archi\cversion\, if so, check that the version
1415 * info (or time stamps if version info is unavailable) is newer (or the
1416 * date is later). If it is, move it to archi\cversion\filexxx.yyy.
1417 * Otherwise, delete the file.
1419 * If a file is not moved to archi\cversion\ because of an error, all the
1420 * rest of the 'unmoved' driver files are removed from archi\. If one or
1421 * more of the driver's files was already moved to archi\cversion\, it
1422 * potentially leaves the driver in a partially updated state. Version
1423 * trauma will most likely occur if an client attempts to use any printer
1424 * bound to the driver. Perhaps a rewrite to make sure the moves can be
1425 * done is appropriate... later JRR
1428 DEBUG(5,("Moving files now !\n"));
1430 if (driver
->driverpath
&& strlen(driver
->driverpath
)) {
1431 slprintf(new_name
, sizeof(new_name
)-1, "%s/%s", architecture
, driver
->driverpath
);
1432 slprintf(old_name
, sizeof(old_name
)-1, "%s/%s", new_dir
, driver
->driverpath
);
1433 if (ver
!= -1 && (ver
=file_version_is_newer(conn
, new_name
, old_name
)) > 0) {
1435 status
= rename_internals(conn
, new_name
, old_name
, True
);
1436 if (!NT_STATUS_IS_OK(status
)) {
1437 DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
1438 new_name
, old_name
));
1439 *perr
= ntstatus_to_werror(status
);
1440 unlink_internals(conn
, 0, new_name
);
1445 unlink_internals(conn
, 0, new_name
);
1448 if (driver
->datafile
&& strlen(driver
->datafile
)) {
1449 if (!strequal(driver
->datafile
, driver
->driverpath
)) {
1450 slprintf(new_name
, sizeof(new_name
)-1, "%s/%s", architecture
, driver
->datafile
);
1451 slprintf(old_name
, sizeof(old_name
)-1, "%s/%s", new_dir
, driver
->datafile
);
1452 if (ver
!= -1 && (ver
=file_version_is_newer(conn
, new_name
, old_name
)) > 0) {
1454 status
= rename_internals(conn
, new_name
, old_name
, True
);
1455 if (!NT_STATUS_IS_OK(status
)) {
1456 DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
1457 new_name
, old_name
));
1458 *perr
= ntstatus_to_werror(status
);
1459 unlink_internals(conn
, 0, new_name
);
1464 unlink_internals(conn
, 0, new_name
);
1468 if (driver
->configfile
&& strlen(driver
->configfile
)) {
1469 if (!strequal(driver
->configfile
, driver
->driverpath
) &&
1470 !strequal(driver
->configfile
, driver
->datafile
)) {
1471 slprintf(new_name
, sizeof(new_name
)-1, "%s/%s", architecture
, driver
->configfile
);
1472 slprintf(old_name
, sizeof(old_name
)-1, "%s/%s", new_dir
, driver
->configfile
);
1473 if (ver
!= -1 && (ver
=file_version_is_newer(conn
, new_name
, old_name
)) > 0) {
1475 status
= rename_internals(conn
, new_name
, old_name
, True
);
1476 if (!NT_STATUS_IS_OK(status
)) {
1477 DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
1478 new_name
, old_name
));
1479 *perr
= ntstatus_to_werror(status
);
1480 unlink_internals(conn
, 0, new_name
);
1485 unlink_internals(conn
, 0, new_name
);
1489 if (driver
->helpfile
&& strlen(driver
->helpfile
)) {
1490 if (!strequal(driver
->helpfile
, driver
->driverpath
) &&
1491 !strequal(driver
->helpfile
, driver
->datafile
) &&
1492 !strequal(driver
->helpfile
, driver
->configfile
)) {
1493 slprintf(new_name
, sizeof(new_name
)-1, "%s/%s", architecture
, driver
->helpfile
);
1494 slprintf(old_name
, sizeof(old_name
)-1, "%s/%s", new_dir
, driver
->helpfile
);
1495 if (ver
!= -1 && (ver
=file_version_is_newer(conn
, new_name
, old_name
)) > 0) {
1497 status
= rename_internals(conn
, new_name
, old_name
, True
);
1498 if (!NT_STATUS_IS_OK(status
)) {
1499 DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
1500 new_name
, old_name
));
1501 *perr
= ntstatus_to_werror(status
);
1502 unlink_internals(conn
, 0, new_name
);
1507 unlink_internals(conn
, 0, new_name
);
1511 if (driver
->dependentfiles
) {
1512 for (i
=0; *driver
->dependentfiles
[i
]; i
++) {
1513 if (!strequal(driver
->dependentfiles
[i
], driver
->driverpath
) &&
1514 !strequal(driver
->dependentfiles
[i
], driver
->datafile
) &&
1515 !strequal(driver
->dependentfiles
[i
], driver
->configfile
) &&
1516 !strequal(driver
->dependentfiles
[i
], driver
->helpfile
)) {
1518 for (j
=0; j
< i
; j
++) {
1519 if (strequal(driver
->dependentfiles
[i
], driver
->dependentfiles
[j
])) {
1524 slprintf(new_name
, sizeof(new_name
)-1, "%s/%s", architecture
, driver
->dependentfiles
[i
]);
1525 slprintf(old_name
, sizeof(old_name
)-1, "%s/%s", new_dir
, driver
->dependentfiles
[i
]);
1526 if (ver
!= -1 && (ver
=file_version_is_newer(conn
, new_name
, old_name
)) > 0) {
1528 status
= rename_internals(conn
, new_name
, old_name
, True
);
1529 if (!NT_STATUS_IS_OK(status
)) {
1530 DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
1531 new_name
, old_name
));
1532 *perr
= ntstatus_to_werror(status
);
1533 unlink_internals(conn
, 0, new_name
);
1538 unlink_internals(conn
, 0, new_name
);
1544 close_cnum(conn
, user
->vuid
);
1547 return ver
== -1 ? False
: True
;
1550 /****************************************************************************
1551 ****************************************************************************/
1552 static uint32
add_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3
*driver
)
1555 fstring architecture
;
1561 TDB_DATA kbuf
, dbuf
;
1563 get_short_archi(architecture
, driver
->environment
);
1565 /* The names are relative. We store them in the form: \print$\arch\version\driver.xxx
1566 * \\server is added in the rpc server layer.
1567 * It does make sense to NOT store the server's name in the printer TDB.
1570 slprintf(directory
, sizeof(directory
)-1, "\\print$\\%s\\%d\\", architecture
, driver
->cversion
);
1572 /* .inf files do not always list a file for each of the four standard files.
1573 * Don't prepend a path to a null filename, or client claims:
1574 * "The server on which the printer resides does not have a suitable
1575 * <printer driver name> printer driver installed. Click OK if you
1576 * wish to install the driver on your local machine."
1578 if (strlen(driver
->driverpath
)) {
1579 fstrcpy(temp_name
, driver
->driverpath
);
1580 slprintf(driver
->driverpath
, sizeof(driver
->driverpath
)-1, "%s%s", directory
, temp_name
);
1583 if (strlen(driver
->datafile
)) {
1584 fstrcpy(temp_name
, driver
->datafile
);
1585 slprintf(driver
->datafile
, sizeof(driver
->datafile
)-1, "%s%s", directory
, temp_name
);
1588 if (strlen(driver
->configfile
)) {
1589 fstrcpy(temp_name
, driver
->configfile
);
1590 slprintf(driver
->configfile
, sizeof(driver
->configfile
)-1, "%s%s", directory
, temp_name
);
1593 if (strlen(driver
->helpfile
)) {
1594 fstrcpy(temp_name
, driver
->helpfile
);
1595 slprintf(driver
->helpfile
, sizeof(driver
->helpfile
)-1, "%s%s", directory
, temp_name
);
1598 if (driver
->dependentfiles
) {
1599 for (i
=0; *driver
->dependentfiles
[i
]; i
++) {
1600 fstrcpy(temp_name
, driver
->dependentfiles
[i
]);
1601 slprintf(driver
->dependentfiles
[i
], sizeof(driver
->dependentfiles
[i
])-1, "%s%s", directory
, temp_name
);
1605 slprintf(key
, sizeof(key
)-1, "%s%s/%d/%s", DRIVERS_PREFIX
, architecture
, driver
->cversion
, driver
->name
);
1607 DEBUG(5,("add_a_printer_driver_3: Adding driver with key %s\n", key
));
1614 len
+= tdb_pack(buf
+len
, buflen
-len
, "dffffffff",
1617 driver
->environment
,
1622 driver
->monitorname
,
1623 driver
->defaultdatatype
);
1625 if (driver
->dependentfiles
) {
1626 for (i
=0; *driver
->dependentfiles
[i
]; i
++) {
1627 len
+= tdb_pack(buf
+len
, buflen
-len
, "f",
1628 driver
->dependentfiles
[i
]);
1632 if (len
!= buflen
) {
1635 tb
= (char *)Realloc(buf
, len
);
1637 DEBUG(0,("add_a_printer_driver_3: failed to enlarge buffer\n!"));
1648 kbuf
.dsize
= strlen(key
)+1;
1652 ret
= tdb_store(tdb_drivers
, kbuf
, dbuf
, TDB_REPLACE
);
1656 DEBUG(0,("add_a_printer_driver_3: Adding driver with key %s failed.\n", key
));
1662 /****************************************************************************
1663 ****************************************************************************/
1664 static uint32
add_a_printer_driver_6(NT_PRINTER_DRIVER_INFO_LEVEL_6
*driver
)
1666 NT_PRINTER_DRIVER_INFO_LEVEL_3 info3
;
1669 info3
.cversion
= driver
->version
;
1670 fstrcpy(info3
.name
,driver
->name
);
1671 fstrcpy(info3
.environment
,driver
->environment
);
1672 fstrcpy(info3
.driverpath
,driver
->driverpath
);
1673 fstrcpy(info3
.datafile
,driver
->datafile
);
1674 fstrcpy(info3
.configfile
,driver
->configfile
);
1675 fstrcpy(info3
.helpfile
,driver
->helpfile
);
1676 fstrcpy(info3
.monitorname
,driver
->monitorname
);
1677 fstrcpy(info3
.defaultdatatype
,driver
->defaultdatatype
);
1678 info3
.dependentfiles
= driver
->dependentfiles
;
1680 return add_a_printer_driver_3(&info3
);
1684 /****************************************************************************
1685 ****************************************************************************/
1686 static WERROR
get_a_printer_driver_3_default(NT_PRINTER_DRIVER_INFO_LEVEL_3
**info_ptr
, fstring driver
, fstring arch
)
1688 NT_PRINTER_DRIVER_INFO_LEVEL_3 info
;
1692 fstrcpy(info
.name
, driver
);
1693 fstrcpy(info
.defaultdatatype
, "RAW");
1695 fstrcpy(info
.driverpath
, "");
1696 fstrcpy(info
.datafile
, "");
1697 fstrcpy(info
.configfile
, "");
1698 fstrcpy(info
.helpfile
, "");
1700 if ((info
.dependentfiles
=(fstring
*)malloc(2*sizeof(fstring
))) == NULL
)
1703 memset(info
.dependentfiles
, '\0', 2*sizeof(fstring
));
1704 fstrcpy(info
.dependentfiles
[0], "");
1706 *info_ptr
= memdup(&info
, sizeof(info
));
1711 /****************************************************************************
1712 ****************************************************************************/
1713 static WERROR
get_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3
**info_ptr
, fstring drivername
, fstring arch
, uint32 version
)
1715 NT_PRINTER_DRIVER_INFO_LEVEL_3 driver
;
1716 TDB_DATA kbuf
, dbuf
;
1717 fstring architecture
;
1722 ZERO_STRUCT(driver
);
1724 get_short_archi(architecture
, arch
);
1726 DEBUG(8,("get_a_printer_driver_3: [%s%s/%d/%s]\n", DRIVERS_PREFIX
, architecture
, version
, drivername
));
1728 slprintf(key
, sizeof(key
)-1, "%s%s/%d/%s", DRIVERS_PREFIX
, architecture
, version
, drivername
);
1731 kbuf
.dsize
= strlen(key
)+1;
1733 dbuf
= tdb_fetch(tdb_drivers
, kbuf
);
1735 return WERR_ACCESS_DENIED
;
1737 len
+= tdb_unpack(dbuf
.dptr
, dbuf
.dsize
, "dffffffff",
1746 driver
.defaultdatatype
);
1749 while (len
< dbuf
.dsize
) {
1752 tddfs
= (fstring
*)Realloc(driver
.dependentfiles
,
1753 sizeof(fstring
)*(i
+2));
1754 if (tddfs
== NULL
) {
1755 DEBUG(0,("get_a_printer_driver_3: failed to enlarge buffer!\n"));
1758 else driver
.dependentfiles
= tddfs
;
1760 len
+= tdb_unpack(dbuf
.dptr
+len
, dbuf
.dsize
-len
, "f",
1761 &driver
.dependentfiles
[i
]);
1764 if (driver
.dependentfiles
!= NULL
)
1765 fstrcpy(driver
.dependentfiles
[i
], "");
1767 SAFE_FREE(dbuf
.dptr
);
1769 if (len
!= dbuf
.dsize
) {
1770 SAFE_FREE(driver
.dependentfiles
);
1772 return get_a_printer_driver_3_default(info_ptr
, drivername
, arch
);
1775 *info_ptr
= (NT_PRINTER_DRIVER_INFO_LEVEL_3
*)memdup(&driver
, sizeof(driver
));
1780 /****************************************************************************
1781 ****************************************************************************/
1782 uint32
get_a_printer_driver_9x_compatible(pstring line
, fstring model
)
1784 NT_PRINTER_DRIVER_INFO_LEVEL_3
*info3
;
1790 slprintf(key
, sizeof(key
)-1, "%s%s/%d/%s", DRIVERS_PREFIX
, "WIN40", 0, model
);
1791 DEBUG(10,("driver key: [%s]\n", key
));
1794 kbuf
.dsize
= strlen(key
)+1;
1795 if (!tdb_exists(tdb_drivers
, kbuf
))
1799 get_a_printer_driver_3(&info3
, model
, "Windows 4.0", 0);
1801 DEBUGADD(10,("info3->name [%s]\n", info3
->name
));
1802 DEBUGADD(10,("info3->datafile [%s]\n", info3
->datafile
));
1803 DEBUGADD(10,("info3->helpfile [%s]\n", info3
->helpfile
));
1804 DEBUGADD(10,("info3->monitorname [%s]\n", info3
->monitorname
));
1805 DEBUGADD(10,("info3->defaultdatatype [%s]\n", info3
->defaultdatatype
));
1806 for (i
=0; info3
->dependentfiles
&& *info3
->dependentfiles
[i
]; i
++) {
1807 DEBUGADD(10,("info3->dependentfiles [%s]\n", info3
->dependentfiles
[i
]));
1809 DEBUGADD(10,("info3->environment [%s]\n", info3
->environment
));
1810 DEBUGADD(10,("info3->driverpath [%s]\n", info3
->driverpath
));
1811 DEBUGADD(10,("info3->configfile [%s]\n", info3
->configfile
));
1813 /*pstrcat(line, info3->name); pstrcat(line, ":");*/
1814 trim_string(info3
->driverpath
, "\\print$\\WIN40\\0\\", 0);
1815 pstrcat(line
, info3
->driverpath
);
1817 trim_string(info3
->datafile
, "\\print$\\WIN40\\0\\", 0);
1818 pstrcat(line
, info3
->datafile
);
1820 trim_string(info3
->helpfile
, "\\print$\\WIN40\\0\\", 0);
1821 pstrcat(line
, info3
->helpfile
);
1823 trim_string(info3
->monitorname
, "\\print$\\WIN40\\0\\", 0);
1824 pstrcat(line
, info3
->monitorname
);
1826 pstrcat(line
, "RAW"); /*info3->defaultdatatype);*/
1829 for (i
=0; info3
->dependentfiles
&& *info3
->dependentfiles
[i
]; i
++) {
1831 pstrcat(line
, ","); /* don't end in a "," */
1832 trim_string(info3
->dependentfiles
[i
], "\\print$\\WIN40\\0\\", 0);
1833 pstrcat(line
, info3
->dependentfiles
[i
]);
1841 /****************************************************************************
1842 Debugging function, dump at level 6 the struct in the logs.
1843 ****************************************************************************/
1845 static uint32
dump_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver
, uint32 level
)
1848 NT_PRINTER_DRIVER_INFO_LEVEL_3
*info3
;
1851 DEBUG(106,("Dumping printer driver at level [%d]\n", level
));
1857 if (driver
.info_3
== NULL
)
1860 info3
=driver
.info_3
;
1862 DEBUGADD(106,("version:[%d]\n", info3
->cversion
));
1863 DEBUGADD(106,("name:[%s]\n", info3
->name
));
1864 DEBUGADD(106,("environment:[%s]\n", info3
->environment
));
1865 DEBUGADD(106,("driverpath:[%s]\n", info3
->driverpath
));
1866 DEBUGADD(106,("datafile:[%s]\n", info3
->datafile
));
1867 DEBUGADD(106,("configfile:[%s]\n", info3
->configfile
));
1868 DEBUGADD(106,("helpfile:[%s]\n", info3
->helpfile
));
1869 DEBUGADD(106,("monitorname:[%s]\n", info3
->monitorname
));
1870 DEBUGADD(106,("defaultdatatype:[%s]\n", info3
->defaultdatatype
));
1872 for (i
=0; info3
->dependentfiles
&&
1873 *info3
->dependentfiles
[i
]; i
++) {
1874 DEBUGADD(106,("dependentfile:[%s]\n",
1875 info3
->dependentfiles
[i
]));
1882 DEBUGADD(106,("dump_a_printer_driver: Level %u not implemented\n", (unsigned int)level
));
1890 /****************************************************************************
1891 ****************************************************************************/
1892 static int pack_devicemode(NT_DEVICEMODE
*nt_devmode
, char *buf
, int buflen
)
1896 len
+= tdb_pack(buf
+len
, buflen
-len
, "p", nt_devmode
);
1898 if (!nt_devmode
) return len
;
1900 len
+= tdb_pack(buf
+len
, buflen
-len
, "ffwwwwwwwwwwwwwwwwwwddddddddddddddp",
1901 nt_devmode
->devicename
,
1902 nt_devmode
->formname
,
1904 nt_devmode
->specversion
,
1905 nt_devmode
->driverversion
,
1907 nt_devmode
->driverextra
,
1908 nt_devmode
->orientation
,
1909 nt_devmode
->papersize
,
1910 nt_devmode
->paperlength
,
1911 nt_devmode
->paperwidth
,
1914 nt_devmode
->defaultsource
,
1915 nt_devmode
->printquality
,
1918 nt_devmode
->yresolution
,
1919 nt_devmode
->ttoption
,
1920 nt_devmode
->collate
,
1921 nt_devmode
->logpixels
,
1924 nt_devmode
->bitsperpel
,
1925 nt_devmode
->pelswidth
,
1926 nt_devmode
->pelsheight
,
1927 nt_devmode
->displayflags
,
1928 nt_devmode
->displayfrequency
,
1929 nt_devmode
->icmmethod
,
1930 nt_devmode
->icmintent
,
1931 nt_devmode
->mediatype
,
1932 nt_devmode
->dithertype
,
1933 nt_devmode
->reserved1
,
1934 nt_devmode
->reserved2
,
1935 nt_devmode
->panningwidth
,
1936 nt_devmode
->panningheight
,
1937 nt_devmode
->private);
1940 if (nt_devmode
->private) {
1941 len
+= tdb_pack(buf
+len
, buflen
-len
, "B",
1942 nt_devmode
->driverextra
,
1943 nt_devmode
->private);
1946 DEBUG(8,("Packed devicemode [%s]\n", nt_devmode
->formname
));
1951 /****************************************************************************
1952 ****************************************************************************/
1953 static int pack_specifics(NT_PRINTER_PARAM
*param
, char *buf
, int buflen
)
1957 while (param
!= NULL
) {
1958 len
+= tdb_pack(buf
+len
, buflen
-len
, "pfdB",
1967 len
+= tdb_pack(buf
+len
, buflen
-len
, "p", param
);
1973 /****************************************************************************
1974 Delete a printer - this just deletes the printer info file, any open
1975 handles are not affected.
1976 ****************************************************************************/
1978 uint32
del_a_printer(char *sharename
)
1983 slprintf(key
, sizeof(key
)-1, "%s%s", PRINTERS_PREFIX
, sharename
);
1986 kbuf
.dsize
=strlen(key
)+1;
1988 tdb_delete(tdb_printers
, kbuf
);
1992 /* FIXME!!! Reorder so this forward declaration is not necessary --jerry */
1993 static WERROR
get_a_printer_2(NT_PRINTER_INFO_LEVEL_2
**, fstring
);
1994 static void free_nt_printer_info_level_2(NT_PRINTER_INFO_LEVEL_2
**);
1995 /****************************************************************************
1996 ****************************************************************************/
1997 static WERROR
update_a_printer_2(NT_PRINTER_INFO_LEVEL_2
*info
)
2003 TDB_DATA kbuf
, dbuf
;
2006 * in addprinter: no servername and the printer is the name
2007 * in setprinter: servername is \\server
2008 * and printer is \\server\\printer
2010 * Samba manages only local printers.
2011 * we currently don't support things like path=\\other_server\printer
2014 if (info
->servername
[0]!='\0') {
2015 trim_string(info
->printername
, info
->servername
, NULL
);
2016 trim_string(info
->printername
, "\\", NULL
);
2017 info
->servername
[0]='\0';
2021 * JFM: one day I'll forget.
2022 * below that's info->portname because that's the SAMBA sharename
2023 * and I made NT 'thinks' it's the portname
2024 * the info->sharename is the thing you can name when you add a printer
2025 * that's the short-name when you create shared printer for 95/98
2026 * So I've made a limitation in SAMBA: you can only have 1 printer model
2027 * behind a SAMBA share.
2035 len
+= tdb_pack(buf
+len
, buflen
-len
, "dddddddddddfffffPfffff",
2038 info
->default_priority
,
2055 info
->printprocessor
,
2059 len
+= pack_devicemode(info
->devmode
, buf
+len
, buflen
-len
);
2061 len
+= pack_specifics(info
->specific
, buf
+len
, buflen
-len
);
2063 if (buflen
!= len
) {
2066 tb
= (char *)Realloc(buf
, len
);
2068 DEBUG(0,("update_a_printer_2: failed to enlarge buffer!\n"));
2078 slprintf(key
, sizeof(key
)-1, "%s%s", PRINTERS_PREFIX
, info
->sharename
);
2081 kbuf
.dsize
= strlen(key
)+1;
2085 ret
= (tdb_store(tdb_printers
, kbuf
, dbuf
, TDB_REPLACE
) == 0? WERR_OK
: WERR_NOMEM
);
2088 if (!W_ERROR_IS_OK(ret
))
2089 DEBUG(8, ("error updating printer to tdb on disk\n"));
2093 DEBUG(8,("packed printer [%s] with driver [%s] portname=[%s] len=%d\n",
2094 info
->sharename
, info
->drivername
, info
->portname
, len
));
2100 /****************************************************************************
2101 ****************************************************************************/
2102 void add_a_specific_param(NT_PRINTER_INFO_LEVEL_2
*info_2
, NT_PRINTER_PARAM
**param
)
2104 NT_PRINTER_PARAM
*current
;
2106 DEBUG(108,("add_a_specific_param\n"));
2108 (*param
)->next
=NULL
;
2110 if (info_2
->specific
== NULL
)
2112 info_2
->specific
=*param
;
2116 current
=info_2
->specific
;
2117 while (current
->next
!= NULL
) {
2118 current
=current
->next
;
2120 current
->next
=*param
;
2126 /****************************************************************************
2127 ****************************************************************************/
2128 BOOL
unlink_specific_param_if_exist(NT_PRINTER_INFO_LEVEL_2
*info_2
, NT_PRINTER_PARAM
*param
)
2130 NT_PRINTER_PARAM
*current
;
2131 NT_PRINTER_PARAM
*previous
;
2133 current
=info_2
->specific
;
2136 if (current
==NULL
) return (False
);
2138 if ( !strcmp(current
->value
, param
->value
) &&
2139 (strlen(current
->value
)==strlen(param
->value
)) ) {
2140 DEBUG(109,("deleting first value\n"));
2141 info_2
->specific
=current
->next
;
2142 SAFE_FREE(current
->data
);
2144 DEBUG(109,("deleted first value\n"));
2148 current
=previous
->next
;
2150 while ( current
!=NULL
) {
2151 if (!strcmp(current
->value
, param
->value
) &&
2152 strlen(current
->value
)==strlen(param
->value
) ) {
2153 DEBUG(109,("deleting current value\n"));
2154 previous
->next
=current
->next
;
2155 SAFE_FREE(current
->data
);
2157 DEBUG(109,("deleted current value\n"));
2161 previous
=previous
->next
;
2162 current
=current
->next
;
2167 /****************************************************************************
2168 Clean up and deallocate a (maybe partially) allocated NT_PRINTER_PARAM.
2169 ****************************************************************************/
2170 void free_nt_printer_param(NT_PRINTER_PARAM
**param_ptr
)
2172 NT_PRINTER_PARAM
*param
= *param_ptr
;
2177 DEBUG(106,("free_nt_printer_param: deleting param [%s]\n", param
->value
));
2179 SAFE_FREE(param
->data
);
2180 SAFE_FREE(*param_ptr
);
2183 /****************************************************************************
2184 Malloc and return an NT devicemode.
2185 ****************************************************************************/
2187 NT_DEVICEMODE
*construct_nt_devicemode(const fstring default_devicename
)
2191 NT_DEVICEMODE
*nt_devmode
= (NT_DEVICEMODE
*)malloc(sizeof(NT_DEVICEMODE
));
2193 if (nt_devmode
== NULL
) {
2194 DEBUG(0,("construct_nt_devicemode: malloc fail.\n"));
2198 ZERO_STRUCTP(nt_devmode
);
2200 safe_strcpy(adevice
, default_devicename
, sizeof(adevice
));
2201 fstrcpy(nt_devmode
->devicename
, adevice
);
2203 fstrcpy(nt_devmode
->formname
, "Letter");
2205 nt_devmode
->specversion
= 0x0401;
2206 nt_devmode
->driverversion
= 0x0400;
2207 nt_devmode
->size
= 0x00DC;
2208 nt_devmode
->driverextra
= 0x0000;
2209 nt_devmode
->fields
= FORMNAME
| TTOPTION
| PRINTQUALITY
|
2210 DEFAULTSOURCE
| COPIES
| SCALE
|
2211 PAPERSIZE
| ORIENTATION
;
2212 nt_devmode
->orientation
= 1;
2213 nt_devmode
->papersize
= PAPER_LETTER
;
2214 nt_devmode
->paperlength
= 0;
2215 nt_devmode
->paperwidth
= 0;
2216 nt_devmode
->scale
= 0x64;
2217 nt_devmode
->copies
= 1;
2218 nt_devmode
->defaultsource
= BIN_FORMSOURCE
;
2219 nt_devmode
->printquality
= RES_HIGH
; /* 0x0258 */
2220 nt_devmode
->color
= COLOR_MONOCHROME
;
2221 nt_devmode
->duplex
= DUP_SIMPLEX
;
2222 nt_devmode
->yresolution
= 0;
2223 nt_devmode
->ttoption
= TT_SUBDEV
;
2224 nt_devmode
->collate
= COLLATE_FALSE
;
2225 nt_devmode
->icmmethod
= 0;
2226 nt_devmode
->icmintent
= 0;
2227 nt_devmode
->mediatype
= 0;
2228 nt_devmode
->dithertype
= 0;
2230 /* non utilisés par un driver d'imprimante */
2231 nt_devmode
->logpixels
= 0;
2232 nt_devmode
->bitsperpel
= 0;
2233 nt_devmode
->pelswidth
= 0;
2234 nt_devmode
->pelsheight
= 0;
2235 nt_devmode
->displayflags
= 0;
2236 nt_devmode
->displayfrequency
= 0;
2237 nt_devmode
->reserved1
= 0;
2238 nt_devmode
->reserved2
= 0;
2239 nt_devmode
->panningwidth
= 0;
2240 nt_devmode
->panningheight
= 0;
2242 nt_devmode
->private = NULL
;
2246 /****************************************************************************
2247 Deepcopy an NT devicemode.
2248 ****************************************************************************/
2250 NT_DEVICEMODE
*dup_nt_devicemode(NT_DEVICEMODE
*nt_devicemode
)
2252 NT_DEVICEMODE
*new_nt_devicemode
= NULL
;
2254 if ((new_nt_devicemode
= (NT_DEVICEMODE
*)memdup(nt_devicemode
, sizeof(NT_DEVICEMODE
))) == NULL
) {
2255 DEBUG(0,("dup_nt_devicemode: malloc fail.\n"));
2259 new_nt_devicemode
->private = NULL
;
2260 if (nt_devicemode
->private != NULL
) {
2261 if ((new_nt_devicemode
->private = memdup(nt_devicemode
->private, nt_devicemode
->driverextra
)) == NULL
) {
2262 SAFE_FREE(new_nt_devicemode
);
2263 DEBUG(0,("dup_nt_devicemode: malloc fail.\n"));
2268 return new_nt_devicemode
;
2271 /****************************************************************************
2272 Clean up and deallocate a (maybe partially) allocated NT_DEVICEMODE.
2273 ****************************************************************************/
2275 void free_nt_devicemode(NT_DEVICEMODE
**devmode_ptr
)
2277 NT_DEVICEMODE
*nt_devmode
= *devmode_ptr
;
2279 if(nt_devmode
== NULL
)
2282 DEBUG(106,("free_nt_devicemode: deleting DEVMODE\n"));
2284 SAFE_FREE(nt_devmode
->private);
2285 SAFE_FREE(*devmode_ptr
);
2288 /****************************************************************************
2289 Clean up and deallocate a (maybe partially) allocated NT_PRINTER_INFO_LEVEL_2.
2290 ****************************************************************************/
2291 static void free_nt_printer_info_level_2(NT_PRINTER_INFO_LEVEL_2
**info_ptr
)
2293 NT_PRINTER_INFO_LEVEL_2
*info
= *info_ptr
;
2294 NT_PRINTER_PARAM
*param_ptr
;
2299 DEBUG(106,("free_nt_printer_info_level_2: deleting info\n"));
2301 free_nt_devicemode(&info
->devmode
);
2303 for(param_ptr
= info
->specific
; param_ptr
; ) {
2304 NT_PRINTER_PARAM
*tofree
= param_ptr
;
2306 param_ptr
= param_ptr
->next
;
2307 free_nt_printer_param(&tofree
);
2310 SAFE_FREE(*info_ptr
);
2314 /****************************************************************************
2315 ****************************************************************************/
2316 static int unpack_devicemode(NT_DEVICEMODE
**nt_devmode
, char *buf
, int buflen
)
2320 NT_DEVICEMODE devmode
;
2322 ZERO_STRUCT(devmode
);
2324 len
+= tdb_unpack(buf
+len
, buflen
-len
, "p", nt_devmode
);
2326 if (!*nt_devmode
) return len
;
2328 len
+= tdb_unpack(buf
+len
, buflen
-len
, "ffwwwwwwwwwwwwwwwwwwddddddddddddddp",
2332 &devmode
.specversion
,
2333 &devmode
.driverversion
,
2335 &devmode
.driverextra
,
2336 &devmode
.orientation
,
2338 &devmode
.paperlength
,
2339 &devmode
.paperwidth
,
2342 &devmode
.defaultsource
,
2343 &devmode
.printquality
,
2346 &devmode
.yresolution
,
2352 &devmode
.bitsperpel
,
2354 &devmode
.pelsheight
,
2355 &devmode
.displayflags
,
2356 &devmode
.displayfrequency
,
2360 &devmode
.dithertype
,
2363 &devmode
.panningwidth
,
2364 &devmode
.panningheight
,
2367 if (devmode
.private) {
2368 /* the len in tdb_unpack is an int value and
2369 * devmode.driverextra is only a short
2371 len
+= tdb_unpack(buf
+len
, buflen
-len
, "B", &extra_len
, &devmode
.private);
2372 devmode
.driverextra
=(uint16
)extra_len
;
2374 /* check to catch an invalid TDB entry so we don't segfault */
2375 if (devmode
.driverextra
== 0) {
2376 devmode
.private = NULL
;
2380 *nt_devmode
= (NT_DEVICEMODE
*)memdup(&devmode
, sizeof(devmode
));
2382 DEBUG(8,("Unpacked devicemode [%s](%s)\n", devmode
.devicename
, devmode
.formname
));
2383 if (devmode
.private)
2384 DEBUG(8,("with a private section of %d bytes\n", devmode
.driverextra
));
2389 /****************************************************************************
2390 ****************************************************************************/
2391 static int unpack_specifics(NT_PRINTER_PARAM
**list
, char *buf
, int buflen
)
2394 NT_PRINTER_PARAM param
, *p
;
2399 len
+= tdb_unpack(buf
+len
, buflen
-len
, "p", &p
);
2402 len
+= tdb_unpack(buf
+len
, buflen
-len
, "fdB",
2408 *list
= memdup(¶m
, sizeof(param
));
2410 DEBUG(8,("specific: [%s], len: %d\n", param
.value
, param
.data_len
));
2416 static void map_to_os2_driver(fstring drivername
)
2418 static BOOL initialised
=False
;
2419 static fstring last_from
,last_to
;
2420 char *mapfile
= lp_os2_driver_map();
2421 char **lines
= NULL
;
2425 if (!strlen(drivername
))
2432 *last_from
= *last_to
= 0;
2436 if (strequal(drivername
,last_from
)) {
2437 DEBUG(3,("Mapped Windows driver %s to OS/2 driver %s\n",drivername
,last_to
));
2438 fstrcpy(drivername
,last_to
);
2442 lines
= file_lines_load(mapfile
, &numlines
);
2443 if (numlines
== 0) {
2444 DEBUG(0,("No entries in OS/2 driver map %s\n",mapfile
));
2448 DEBUG(4,("Scanning OS/2 driver map %s\n",mapfile
));
2450 for( i
= 0; i
< numlines
; i
++) {
2451 char *nt_name
= lines
[i
];
2452 char *os2_name
= strchr(nt_name
,'=');
2459 while (isspace(*nt_name
))
2462 if (!*nt_name
|| strchr("#;",*nt_name
))
2466 int l
= strlen(nt_name
);
2467 while (l
&& isspace(nt_name
[l
-1])) {
2473 while (isspace(*os2_name
))
2477 int l
= strlen(os2_name
);
2478 while (l
&& isspace(os2_name
[l
-1])) {
2484 if (strequal(nt_name
,drivername
)) {
2485 DEBUG(3,("Mapped windows driver %s to os2 driver%s\n",drivername
,os2_name
));
2486 fstrcpy(last_from
,drivername
);
2487 fstrcpy(last_to
,os2_name
);
2488 fstrcpy(drivername
,os2_name
);
2489 file_lines_free(lines
);
2494 file_lines_free(lines
);
2497 /****************************************************************************
2498 get a default printer info 2 struct
2499 ****************************************************************************/
2500 static WERROR
get_a_printer_2_default(NT_PRINTER_INFO_LEVEL_2
**info_ptr
, fstring sharename
)
2503 NT_PRINTER_INFO_LEVEL_2 info
;
2507 snum
= lp_servicenumber(sharename
);
2509 slprintf(info
.servername
, sizeof(info
.servername
)-1, "\\\\%s", get_called_name());
2510 slprintf(info
.printername
, sizeof(info
.printername
)-1, "\\\\%s\\%s",
2511 get_called_name(), sharename
);
2512 fstrcpy(info
.sharename
, sharename
);
2513 fstrcpy(info
.portname
, SAMBA_PRINTER_PORT_NAME
);
2514 fstrcpy(info
.drivername
, lp_printerdriver(snum
));
2516 /* by setting the driver name to an empty string, a local NT admin
2517 can now run the **local** APW to install a local printer driver
2518 for a Samba shared printer in 2.2. Without this, drivers **must** be
2519 installed on the Samba server for NT clients --jerry */
2520 #if 0 /* JERRY --do not uncomment-- */
2521 if (!*info
.drivername
)
2522 fstrcpy(info
.drivername
, "NO DRIVER AVAILABLE FOR THIS PRINTER");
2526 DEBUG(10,("get_a_printer_2_default: driver name set to [%s]\n", info
.drivername
));
2528 pstrcpy(info
.comment
, "");
2529 fstrcpy(info
.printprocessor
, "winprint");
2530 fstrcpy(info
.datatype
, "RAW");
2532 info
.attributes
= PRINTER_ATTRIBUTE_SHARED
| PRINTER_ATTRIBUTE_NETWORK
; /* attributes */
2534 info
.starttime
= 0; /* Minutes since 12:00am GMT */
2535 info
.untiltime
= 0; /* Minutes since 12:00am GMT */
2537 info
.default_priority
= 1;
2538 info
.setuptime
= (uint32
)time(NULL
);
2541 * I changed this as I think it is better to have a generic
2542 * DEVMODE than to crash Win2k explorer.exe --jerry
2543 * See the HP Deskjet 990c Win2k drivers for an example.
2545 * However the default devmode appears to cause problems
2546 * with the HP CLJ 8500 PCL driver. Hence the addition of
2547 * the "default devmode" parameter --jerry 22/01/2002
2550 if (lp_default_devmode(snum
)) {
2551 if ((info
.devmode
= construct_nt_devicemode(info
.printername
)) == NULL
)
2555 info
.devmode
= NULL
;
2558 /* This will get the current RPC talloc context, but we should be
2559 passing this as a parameter... fixme... JRA ! */
2561 if (!nt_printing_getsec(get_talloc_ctx(), sharename
, &info
.secdesc_buf
))
2564 *info_ptr
= (NT_PRINTER_INFO_LEVEL_2
*)memdup(&info
, sizeof(info
));
2566 DEBUG(0,("get_a_printer_2_default: malloc fail.\n"));
2574 free_nt_devicemode(&info
.devmode
);
2575 return WERR_ACCESS_DENIED
;
2578 /****************************************************************************
2579 ****************************************************************************/
2580 static WERROR
get_a_printer_2(NT_PRINTER_INFO_LEVEL_2
**info_ptr
, fstring sharename
)
2583 NT_PRINTER_INFO_LEVEL_2 info
;
2585 TDB_DATA kbuf
, dbuf
;
2586 fstring printername
;
2590 slprintf(key
, sizeof(key
)-1, "%s%s", PRINTERS_PREFIX
, sharename
);
2593 kbuf
.dsize
= strlen(key
)+1;
2595 dbuf
= tdb_fetch(tdb_printers
, kbuf
);
2597 return get_a_printer_2_default(info_ptr
, sharename
);
2599 len
+= tdb_unpack(dbuf
.dptr
+len
, dbuf
.dsize
-len
, "dddddddddddfffffPfffff",
2602 &info
.default_priority
,
2619 info
.printprocessor
,
2623 /* Samba has to have shared raw drivers. */
2624 info
.attributes
|= (PRINTER_ATTRIBUTE_SHARED
| PRINTER_ATTRIBUTE_NETWORK
);
2626 /* Restore the stripped strings. */
2627 slprintf(info
.servername
, sizeof(info
.servername
)-1, "\\\\%s", get_called_name());
2628 slprintf(printername
, sizeof(printername
)-1, "\\\\%s\\%s", get_called_name(),
2630 fstrcpy(info
.printername
, printername
);
2632 len
+= unpack_devicemode(&info
.devmode
,dbuf
.dptr
+len
, dbuf
.dsize
-len
);
2635 * Some client drivers freak out if there is a NULL devmode
2636 * (probably the driver is not checking before accessing
2637 * the devmode pointer) --jerry
2639 * See comments in get_a_printer_2_default()
2642 if (lp_default_devmode(lp_servicenumber(sharename
)) && !info
.devmode
)
2644 DEBUG(8,("get_a_printer_2: Constructing a default device mode for [%s]\n",
2646 info
.devmode
= construct_nt_devicemode(printername
);
2649 len
+= unpack_specifics(&info
.specific
,dbuf
.dptr
+len
, dbuf
.dsize
-len
);
2651 /* This will get the current RPC talloc context, but we should be
2652 passing this as a parameter... fixme... JRA ! */
2654 nt_printing_getsec(get_talloc_ctx(), sharename
, &info
.secdesc_buf
);
2656 /* Fix for OS/2 drivers. */
2658 if (get_remote_arch() == RA_OS2
)
2659 map_to_os2_driver(info
.drivername
);
2661 SAFE_FREE(dbuf
.dptr
);
2662 *info_ptr
=memdup(&info
, sizeof(info
));
2664 DEBUG(9,("Unpacked printer [%s] name [%s] running driver [%s]\n",
2665 sharename
, info
.printername
, info
.drivername
));
2670 /****************************************************************************
2671 debugging function, dump at level 6 the struct in the logs
2672 ****************************************************************************/
2673 static uint32
dump_a_printer(NT_PRINTER_INFO_LEVEL printer
, uint32 level
)
2676 NT_PRINTER_INFO_LEVEL_2
*info2
;
2678 DEBUG(106,("Dumping printer at level [%d]\n", level
));
2684 if (printer
.info_2
== NULL
)
2688 info2
=printer
.info_2
;
2690 DEBUGADD(106,("attributes:[%d]\n", info2
->attributes
));
2691 DEBUGADD(106,("priority:[%d]\n", info2
->priority
));
2692 DEBUGADD(106,("default_priority:[%d]\n", info2
->default_priority
));
2693 DEBUGADD(106,("starttime:[%d]\n", info2
->starttime
));
2694 DEBUGADD(106,("untiltime:[%d]\n", info2
->untiltime
));
2695 DEBUGADD(106,("status:[%d]\n", info2
->status
));
2696 DEBUGADD(106,("cjobs:[%d]\n", info2
->cjobs
));
2697 DEBUGADD(106,("averageppm:[%d]\n", info2
->averageppm
));
2698 DEBUGADD(106,("changeid:[%d]\n", info2
->changeid
));
2699 DEBUGADD(106,("c_setprinter:[%d]\n", info2
->c_setprinter
));
2700 DEBUGADD(106,("setuptime:[%d]\n", info2
->setuptime
));
2702 DEBUGADD(106,("servername:[%s]\n", info2
->servername
));
2703 DEBUGADD(106,("printername:[%s]\n", info2
->printername
));
2704 DEBUGADD(106,("sharename:[%s]\n", info2
->sharename
));
2705 DEBUGADD(106,("portname:[%s]\n", info2
->portname
));
2706 DEBUGADD(106,("drivername:[%s]\n", info2
->drivername
));
2707 DEBUGADD(106,("comment:[%s]\n", info2
->comment
));
2708 DEBUGADD(106,("location:[%s]\n", info2
->location
));
2709 DEBUGADD(106,("sepfile:[%s]\n", info2
->sepfile
));
2710 DEBUGADD(106,("printprocessor:[%s]\n", info2
->printprocessor
));
2711 DEBUGADD(106,("datatype:[%s]\n", info2
->datatype
));
2712 DEBUGADD(106,("parameters:[%s]\n", info2
->parameters
));
2718 DEBUGADD(106,("dump_a_printer: Level %u not implemented\n", (unsigned int)level
));
2726 /****************************************************************************
2727 Get the parameters we can substitute in an NT print job.
2728 ****************************************************************************/
2730 void get_printer_subst_params(int snum
, fstring
*printername
, fstring
*sharename
, fstring
*portname
)
2732 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
2734 **printername
= **sharename
= **portname
= '\0';
2736 if (!W_ERROR_IS_OK(get_a_printer(&printer
, 2, lp_servicename(snum
))))
2739 fstrcpy(*printername
, printer
->info_2
->printername
);
2740 fstrcpy(*sharename
, printer
->info_2
->sharename
);
2741 fstrcpy(*portname
, printer
->info_2
->portname
);
2743 free_a_printer(&printer
, 2);
2746 /****************************************************************************
2747 Update the changeid time.
2748 This is SO NASTY as some drivers need this to change, others need it
2749 static. This value will change every second, and I must hope that this
2750 is enough..... DON'T CHANGE THIS CODE WITHOUT A TEST MATRIX THE SIZE OF
2752 ****************************************************************************/
2754 static uint32
rev_changeid(void)
2758 get_process_uptime(&tv
);
2761 /* Return changeid as msec since spooler restart */
2762 return tv
.tv_sec
* 1000 + tv
.tv_usec
/ 1000;
2765 * This setting seems to work well but is too untested
2766 * to replace the above calculation. Left in for experiementation
2767 * of the reader --jerry (Tue Mar 12 09:15:05 CST 2002)
2769 return tv
.tv_sec
* 10 + tv
.tv_usec
/ 100000;
2774 * The function below are the high level ones.
2775 * only those ones must be called from the spoolss code.
2779 /****************************************************************************
2780 Modify a printer. This is called from SETPRINTERDATA/DELETEPRINTERDATA.
2781 ****************************************************************************/
2783 WERROR
mod_a_printer(NT_PRINTER_INFO_LEVEL printer
, uint32 level
)
2787 dump_a_printer(printer
, level
);
2794 * Update the changestamp. Emperical tests show that the
2795 * ChangeID is always updated,but c_setprinter is
2796 * global spooler variable (not per printer).
2799 /* ChangeID **must** be increasing over the lifetime
2800 of client's spoolss service in order for the
2801 client's cache to show updates */
2803 printer
.info_2
->changeid
= rev_changeid();
2806 * Because one day someone will ask:
2807 * NT->NT An admin connection to a remote
2808 * printer show changes imeediately in
2809 * the properities dialog
2811 * A non-admin connection will only show the
2812 * changes after viewing the properites page
2813 * 2 times. Seems to be related to a
2814 * race condition in the client between the spooler
2815 * updating the local cache and the Explorer.exe GUI
2816 * actually displaying the properties.
2818 * This is fixed in Win2k. admin/non-admin
2819 * connections both display changes immediately.
2824 result
=update_a_printer_2(printer
.info_2
);
2828 result
=WERR_UNKNOWN_LEVEL
;
2835 /****************************************************************************
2836 Initialize printer devmode & data with previously saved driver init values.
2837 ****************************************************************************/
2839 static BOOL
set_driver_init_2(NT_PRINTER_INFO_LEVEL_2
*info_ptr
)
2843 TDB_DATA kbuf
, dbuf
;
2844 NT_PRINTER_PARAM
*current
;
2845 NT_PRINTER_INFO_LEVEL_2 info
;
2848 * Delete any printer data 'specifics' already set. When called for driver
2849 * replace, there will generally be some, but during an add printer, there
2850 * should not be any (if there are delete them).
2852 while ( (current
=info_ptr
->specific
) != NULL
) {
2853 info_ptr
->specific
=current
->next
;
2854 SAFE_FREE(current
->data
);
2860 slprintf(key
, sizeof(key
)-1, "%s%s", DRIVER_INIT_PREFIX
, info_ptr
->drivername
);
2863 kbuf
.dsize
= strlen(key
)+1;
2865 dbuf
= tdb_fetch(tdb_drivers
, kbuf
);
2868 * When changing to a driver that has no init info in the tdb, remove
2869 * the previous drivers init info and leave the new on blank.
2871 free_nt_devicemode(&info_ptr
->devmode
);
2876 * Get the saved DEVMODE..
2878 len
+= unpack_devicemode(&info
.devmode
,dbuf
.dptr
+len
, dbuf
.dsize
-len
);
2881 * The saved DEVMODE contains the devicename from the printer used during
2882 * the initialization save. Change it to reflect the new printer.
2884 ZERO_STRUCT(info
.devmode
->devicename
);
2885 fstrcpy(info
.devmode
->devicename
, info_ptr
->printername
);
2889 * NT/2k does not change out the entire DeviceMode of a printer
2890 * when changing the driver. Only the driverextra, private, &
2891 * driverversion fields. --jerry (Thu Mar 14 08:58:43 CST 2002)
2893 * Later e4xamination revealed that Windows NT/2k does reset the
2894 * the printer's device mode, bit **only** when you change a
2895 * property of the device mode such as the page orientation.
2902 * Bind the saved DEVMODE to the new the printer.
2904 free_nt_devicemode(&info_ptr
->devmode
);
2905 info_ptr
->devmode
= info
.devmode
;
2907 /* copy the entire devmode if we currently don't have one */
2909 if (!info_ptr
->devmode
) {
2910 DEBUG(10,("set_driver_init_2: Current Devmode is NULL. Copying entire Device Mode\n"));
2911 info_ptr
->devmode
= info
.devmode
;
2914 /* only set the necessary fields */
2916 DEBUG(10,("set_driver_init_2: Setting driverversion [0x%x] and private data [0x%x]\n",
2917 info
.devmode
->driverversion
, info
.devmode
->driverextra
));
2919 info_ptr
->devmode
->driverversion
= info
.devmode
->driverversion
;
2921 SAFE_FREE(info_ptr
->devmode
->private);
2922 info_ptr
->devmode
->private = NULL
;
2924 if (info
.devmode
->driverversion
)
2925 info_ptr
->devmode
->private = memdup(info
.devmode
->private, info
.devmode
->driverversion
);
2927 free_nt_devicemode(&info
.devmode
);
2931 DEBUG(10,("set_driver_init_2: Set printer [%s] init DEVMODE for driver [%s]\n",
2932 info_ptr
->printername
, info_ptr
->drivername
));
2935 * Add the printer data 'specifics' to the new printer
2937 len
+= unpack_specifics(&info_ptr
->specific
,dbuf
.dptr
+len
, dbuf
.dsize
-len
);
2939 SAFE_FREE(dbuf
.dptr
);
2944 /****************************************************************************
2945 Initialize printer devmode & data with previously saved driver init values.
2946 When a printer is created using AddPrinter, the drivername bound to the
2947 printer is used to lookup previously saved driver initialization info, which
2948 is bound to the new printer.
2949 ****************************************************************************/
2951 BOOL
set_driver_init(NT_PRINTER_INFO_LEVEL
*printer
, uint32 level
)
2953 BOOL result
= False
;
2958 result
=set_driver_init_2(printer
->info_2
);
2962 DEBUG(0,("set_driver_init: Programmer's error! Unknown driver_init level [%d]\n",
2970 /****************************************************************************
2971 Delete driver init data stored for a specified driver
2972 ****************************************************************************/
2974 BOOL
del_driver_init(char *drivername
)
2979 if (!drivername
|| !*drivername
) {
2980 DEBUG(3,("del_driver_init: No drivername specified!\n"));
2984 slprintf(key
, sizeof(key
)-1, "%s%s", DRIVER_INIT_PREFIX
, drivername
);
2987 kbuf
.dsize
= strlen(key
)+1;
2989 DEBUG(6,("del_driver_init: Removing driver init data for [%s]\n", drivername
));
2991 return (tdb_delete(tdb_drivers
, kbuf
) == 0);
2994 /****************************************************************************
2995 Pack up the DEVMODE and specifics for a printer into a 'driver init' entry
2996 in the tdb. Note: this is different from the driver entry and the printer
2997 entry. There should be a single driver init entry for each driver regardless
2998 of whether it was installed from NT or 2K. Technically, they should be
2999 different, but they work out to the same struct.
3000 ****************************************************************************/
3002 static uint32
update_driver_init_2(NT_PRINTER_INFO_LEVEL_2
*info
)
3006 int buflen
, len
, ret
;
3007 TDB_DATA kbuf
, dbuf
;
3014 len
+= pack_devicemode(info
->devmode
, buf
+len
, buflen
-len
);
3016 len
+= pack_specifics(info
->specific
, buf
+len
, buflen
-len
);
3018 if (buflen
!= len
) {
3021 tb
= (char *)Realloc(buf
, len
);
3023 DEBUG(0, ("update_driver_init_2: failed to enlarge buffer!\n"));
3032 slprintf(key
, sizeof(key
)-1, "%s%s", DRIVER_INIT_PREFIX
, info
->drivername
);
3035 kbuf
.dsize
= strlen(key
)+1;
3039 ret
= tdb_store(tdb_drivers
, kbuf
, dbuf
, TDB_REPLACE
);
3043 DEBUG(8, ("update_driver_init_2: error updating printer init to tdb on disk\n"));
3047 DEBUG(10,("update_driver_init_2: Saved printer [%s] init DEVMODE & specifics for driver [%s]\n",
3048 info
->sharename
, info
->drivername
));
3053 /****************************************************************************
3054 Update (i.e. save) the driver init info (DEVMODE and specifics) for a printer
3055 ****************************************************************************/
3057 uint32
update_driver_init(NT_PRINTER_INFO_LEVEL printer
, uint32 level
)
3061 dump_a_printer(printer
, level
);
3067 result
=update_driver_init_2(printer
.info_2
);
3078 /****************************************************************************
3079 Convert the printer data value, a REG_BINARY array, into an initialization
3080 DEVMODE. Note: the array must be parsed as if it was a DEVMODE in an rpc...
3081 got to keep the endians happy :).
3082 ****************************************************************************/
3084 static BOOL
convert_driver_init(NT_PRINTER_PARAM
*param
, TALLOC_CTX
*ctx
, NT_DEVICEMODE
*nt_devmode
)
3086 BOOL result
= False
;
3090 ZERO_STRUCT(devmode
);
3092 prs_init(&ps
, 0, ctx
, UNMARSHALL
);
3093 ps
.data_p
= (char *)param
->data
;
3094 ps
.buffer_size
= param
->data_len
;
3096 if (spoolss_io_devmode("phantom DEVMODE", &ps
, 0, &devmode
))
3097 result
= convert_devicemode("", &devmode
, &nt_devmode
);
3099 DEBUG(10,("convert_driver_init: error parsing DEVMODE\n"));
3104 /****************************************************************************
3105 Set the DRIVER_INIT info in the tdb. Requires Win32 client code that:
3107 1. Use the driver's config DLL to this UNC printername and:
3108 a. Call DrvPrintEvent with PRINTER_EVENT_INITIALIZE
3109 b. Call DrvConvertDevMode with CDM_DRIVER_DEFAULT to get default DEVMODE
3110 2. Call SetPrinterData with the 'magic' key and the DEVMODE as data.
3112 The last step triggers saving the "driver initialization" information for
3113 this printer into the tdb. Later, new printers that use this driver will
3114 have this initialization information bound to them. This simulates the
3115 driver initialization, as if it had run on the Samba server (as it would
3118 The Win32 client side code requirement sucks! But until we can run arbitrary
3119 Win32 printer driver code on any Unix that Samba runs on, we are stuck with it.
3121 It would have been easier to use SetPrinter because all the UNMARSHALLING of
3122 the DEVMODE is done there, but 2K/XP clients do not set the DEVMODE... think
3123 about it and you will realize why. JRR 010720
3124 ****************************************************************************/
3126 static WERROR
save_driver_init_2(NT_PRINTER_INFO_LEVEL
*printer
, NT_PRINTER_PARAM
*param
)
3128 WERROR status
= WERR_OK
;
3129 TALLOC_CTX
*ctx
= NULL
;
3130 NT_DEVICEMODE
*nt_devmode
= NULL
;
3131 NT_DEVICEMODE
*tmp_devmode
= printer
->info_2
->devmode
;
3134 * When the DEVMODE is already set on the printer, don't try to unpack it.
3137 if (!printer
->info_2
->devmode
&& param
->data_len
) {
3139 * Set devmode on printer info, so entire printer initialization can be
3143 if ((ctx
= talloc_init()) == NULL
)
3146 if ((nt_devmode
= (NT_DEVICEMODE
*)malloc(sizeof(NT_DEVICEMODE
))) == NULL
) {
3147 status
= WERR_NOMEM
;
3151 ZERO_STRUCTP(nt_devmode
);
3154 * The DEVMODE is held in the 'data' component of the param in raw binary.
3155 * Convert it to to a devmode structure
3157 if (!convert_driver_init(param
, ctx
, nt_devmode
)) {
3158 DEBUG(10,("save_driver_init_2: error converting DEVMODE\n"));
3159 status
= WERR_INVALID_PARAM
;
3163 printer
->info_2
->devmode
= nt_devmode
;
3167 * Pack up and add (or update) the DEVMODE and any current printer data to
3168 * a 'driver init' element in the tdb
3172 if (update_driver_init(*printer
, 2)!=0) {
3173 DEBUG(10,("save_driver_init_2: error updating DEVMODE\n"));
3174 status
= WERR_NOMEM
;
3179 * If driver initialization info was successfully saved, set the current
3180 * printer to match it. This allows initialization of the current printer
3181 * as well as the driver.
3183 status
= mod_a_printer(*printer
, 2);
3184 if (!W_ERROR_IS_OK(status
)) {
3185 DEBUG(10,("save_driver_init_2: error setting DEVMODE on printer [%s]\n",
3186 printer
->info_2
->printername
));
3190 srv_spoolss_sendnotify(p
, handle
);
3194 talloc_destroy(ctx
);
3196 SAFE_FREE(nt_devmode
->private);
3197 SAFE_FREE(nt_devmode
);
3198 printer
->info_2
->devmode
= tmp_devmode
;
3203 /****************************************************************************
3204 Update the driver init info (DEVMODE and specifics) for a printer
3205 ****************************************************************************/
3207 WERROR
save_driver_init(NT_PRINTER_INFO_LEVEL
*printer
, uint32 level
, NT_PRINTER_PARAM
*param
)
3209 WERROR status
= WERR_OK
;
3215 status
=save_driver_init_2(printer
, param
);
3219 status
=WERR_UNKNOWN_LEVEL
;
3226 /****************************************************************************
3227 Get a NT_PRINTER_INFO_LEVEL struct. It returns malloced memory.
3228 ****************************************************************************/
3230 WERROR
get_a_printer(NT_PRINTER_INFO_LEVEL
**pp_printer
, uint32 level
, fstring sharename
)
3233 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
3237 DEBUG(10,("get_a_printer: [%s] level %u\n", sharename
, (unsigned int)level
));
3243 if ((printer
= (NT_PRINTER_INFO_LEVEL
*)malloc(sizeof(NT_PRINTER_INFO_LEVEL
))) == NULL
) {
3244 DEBUG(0,("get_a_printer: malloc fail.\n"));
3247 ZERO_STRUCTP(printer
);
3248 result
=get_a_printer_2(&printer
->info_2
, sharename
);
3249 if (W_ERROR_IS_OK(result
)) {
3250 dump_a_printer(*printer
, level
);
3251 *pp_printer
= printer
;
3258 result
=WERR_UNKNOWN_LEVEL
;
3262 DEBUG(10,("get_a_printer: [%s] level %u returning %s\n", sharename
, (unsigned int)level
, dos_errstr(result
)));
3267 /****************************************************************************
3268 Deletes a NT_PRINTER_INFO_LEVEL struct.
3269 ****************************************************************************/
3271 uint32
free_a_printer(NT_PRINTER_INFO_LEVEL
**pp_printer
, uint32 level
)
3274 NT_PRINTER_INFO_LEVEL
*printer
= *pp_printer
;
3276 DEBUG(104,("freeing a printer at level [%d]\n", level
));
3278 if (printer
== NULL
)
3285 if (printer
->info_2
!= NULL
)
3287 free_nt_printer_info_level_2(&printer
->info_2
);
3301 SAFE_FREE(*pp_printer
);
3305 /****************************************************************************
3306 ****************************************************************************/
3307 uint32
add_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver
, uint32 level
)
3310 DEBUG(104,("adding a printer at level [%d]\n", level
));
3311 dump_a_printer_driver(driver
, level
);
3317 result
=add_a_printer_driver_3(driver
.info_3
);
3323 result
=add_a_printer_driver_6(driver
.info_6
);
3333 /****************************************************************************
3334 ****************************************************************************/
3335 WERROR
get_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL
*driver
, uint32 level
,
3336 fstring drivername
, fstring architecture
, uint32 version
)
3343 /* Sometime we just want any version of the driver */
3345 if ( version
== DRIVER_ANY_VERSION
) {
3346 /* look for Win2k first and then for NT4 */
3347 result
= get_a_printer_driver_3(&driver
->info_3
, drivername
,
3350 if ( !W_ERROR_IS_OK(result
) ) {
3351 result
= get_a_printer_driver_3( &driver
->info_3
,
3352 drivername
, architecture
, 2 );
3356 result
= get_a_printer_driver_3(&driver
->info_3
, drivername
,
3357 architecture
, version
);
3366 if (W_ERROR_IS_OK(result
))
3367 dump_a_printer_driver(*driver
, level
);
3372 /****************************************************************************
3373 ****************************************************************************/
3374 uint32
free_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver
, uint32 level
)
3382 NT_PRINTER_DRIVER_INFO_LEVEL_3
*info3
;
3383 if (driver
.info_3
!= NULL
)
3385 info3
=driver
.info_3
;
3386 SAFE_FREE(info3
->dependentfiles
);
3387 ZERO_STRUCTP(info3
);
3399 NT_PRINTER_DRIVER_INFO_LEVEL_6
*info6
;
3400 if (driver
.info_6
!= NULL
)
3402 info6
=driver
.info_6
;
3403 SAFE_FREE(info6
->dependentfiles
);
3404 SAFE_FREE(info6
->previousnames
);
3405 ZERO_STRUCTP(info6
);
3423 /****************************************************************************
3424 Determine whether or not a particular driver is currently assigned
3426 ****************************************************************************/
3428 BOOL
printer_driver_in_use ( NT_PRINTER_DRIVER_INFO_LEVEL_3
*i
)
3431 int n_services
= lp_numservices();
3432 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
3437 DEBUG(5,("printer_driver_in_use: Beginning search through ntprinters.tdb...\n"));
3439 /* loop through the printers.tdb and check for the drivername */
3441 for (snum
=0; snum
<n_services
; snum
++)
3443 if ( !(lp_snum_ok(snum
) && lp_print_ok(snum
) ) )
3446 if ( !W_ERROR_IS_OK(get_a_printer(&printer
, 2, lp_servicename(snum
))) )
3449 if ( !StrCaseCmp(i
->name
, printer
->info_2
->drivername
) ) {
3450 free_a_printer( &printer
, 2 );
3454 free_a_printer( &printer
, 2 );
3457 DEBUG(5,("printer_driver_in_use: Completed search through ntprinters.tdb...\n"));
3459 /* report that the driver is not in use by default */
3465 /**********************************************************************
3466 Check to see if a ogiven file is in use by *info
3467 *********************************************************************/
3469 static BOOL
drv_file_in_use( char* file
, NT_PRINTER_DRIVER_INFO_LEVEL_3
*info
)
3476 if ( strequal(file
, info
->driverpath
) )
3479 if ( strequal(file
, info
->datafile
) )
3482 if ( strequal(file
, info
->configfile
) )
3485 if ( strequal(file
, info
->helpfile
) )
3488 s
= (char*) info
->dependentfiles
;
3493 if ( strequal(file
, s
) )
3503 /**********************************************************************
3504 Utility function to remove the dependent file pointed to by the
3505 input parameter from the list
3506 *********************************************************************/
3508 static void trim_dependent_file( char* s
)
3512 /* set p to the next character string in the list */
3514 p
= s
+ strlen( s
) + 1;
3516 /* check to see that we have another string to copy back */
3520 /* loop over s copying characters from p to s */
3521 while ( *p
!='\0' && *(p
+1)!='\0' )
3525 /* add the two trailing NULL's */
3531 /**********************************************************************
3532 Check if any of the files used by src are also used by drv
3533 *********************************************************************/
3535 static BOOL
trim_overlap_drv_files( NT_PRINTER_DRIVER_INFO_LEVEL_3
*src
,
3536 NT_PRINTER_DRIVER_INFO_LEVEL_3
*drv
)
3538 BOOL in_use
= False
;
3544 /* check each file. Remove it from the src structure if it overlaps */
3546 if ( drv_file_in_use(src
->driverpath
, drv
) ) {
3548 fstrcpy( src
->driverpath
, "" );
3551 if ( drv_file_in_use(src
->datafile
, drv
) ) {
3553 fstrcpy( src
->datafile
, "" );
3556 if ( drv_file_in_use(src
->configfile
, drv
) ) {
3558 fstrcpy( src
->configfile
, "" );
3561 s
= (char*)src
->dependentfiles
;
3566 if ( drv_file_in_use(s
, drv
) ) {
3568 trim_dependent_file( s
);
3579 /****************************************************************************
3580 Determine whether or not a particular driver files are currently being
3581 used by any other driver.
3583 Return value is True if any files were in use by other drivers
3584 and False otherwise.
3586 Upon return, *info has been modified to only contain the driver files
3587 which are not in use
3588 ****************************************************************************/
3590 BOOL
printer_driver_files_in_use ( NT_PRINTER_DRIVER_INFO_LEVEL_3
*info
)
3595 fstring
*list
= NULL
;
3596 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
3598 /* loop over all driver versions */
3600 DEBUG(5,("printer_driver_files_in_use: Beginning search through ntdrivers.tdb...\n"));
3602 for ( version
=0; version
<DRIVER_MAX_VERSION
; version
++ )
3604 /* get the list of drivers */
3607 ndrivers
= get_ntdrivers(&list
, info
->environment
, version
);
3609 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n",
3610 ndrivers
, info
->environment
, version
));
3615 /* check each driver for overlap in files */
3617 for (i
=0; i
<ndrivers
; i
++)
3619 DEBUGADD(5,("\tdriver: [%s]\n", list
[i
]));
3621 ZERO_STRUCT(driver
);
3623 if ( !W_ERROR_IS_OK(get_a_printer_driver(&driver
, 3, list
[i
],
3624 info
->environment
, version
)) )
3630 /* check if d2 uses any files from d1 */
3631 /* only if this is a different driver than the one being deleted */
3633 if ( !strequal(info
->name
, driver
.info_3
->name
)
3634 || (info
->cversion
!= driver
.info_3
->cversion
) )
3636 if ( trim_overlap_drv_files(info
, driver
.info_3
) ) {
3637 free_a_printer_driver(driver
, 3);
3643 free_a_printer_driver(driver
, 3);
3649 DEBUG(5,("printer_driver_files_in_use: Completed search through ntdrivers.tdb...\n"));
3654 /****************************************************************************
3655 Actually delete the driver files. Make sure that
3656 printer_driver_files_in_use() return False before calling
3658 ****************************************************************************/
3660 static NTSTATUS
delete_driver_files( NT_PRINTER_DRIVER_INFO_LEVEL_3
*i
)
3665 return NT_STATUS_ACCESS_DENIED
;
3667 DEBUG(6,("delete_driver_files: deleting driver [%s] - version [%d]\n", i
->name
, i
->cversion
));
3670 if ( *i
->driverpath
)
3671 DEBUG(10,("deleting [%s]\n", i
->driverpath
));
3672 if ( *i
->configfile
)
3673 DEBUG(10,("deleting [%s]\n", i
->configfile
));
3675 DEBUG(10,("deleting [%s]\n", i
->datafile
));
3677 DEBUG(10,("deleting [%s]\n", i
->helpfile
));
3679 s
= (char*)i
->dependentfiles
;
3683 DEBUG(10,("deleting dependent file [%s]\n", s
));
3684 s
+= strlen( s
) + 1;
3688 return NT_STATUS_OK
;
3691 /****************************************************************************
3692 Remove a printer driver from the TDB. This assumes that the the driver was
3693 previously looked up.
3694 ***************************************************************************/
3695 WERROR
delete_printer_driver (NT_PRINTER_DRIVER_INFO_LEVEL_3
*i
, BOOL delete_files
)
3701 /* delete the tdb data first */
3703 get_short_archi(arch
, i
->environment
);
3704 slprintf(key
, sizeof(key
)-1, "%s%s/%d/%s", DRIVERS_PREFIX
,
3705 arch
, i
->cversion
, i
->name
);
3707 DEBUG(5,("delete_printer_driver: key = [%s] delete_files = %s\n",
3708 key
, delete_files
? "TRUE" : "FALSE" ));
3711 kbuf
.dsize
=strlen(key
)+1;
3713 if (tdb_delete(tdb_drivers
, kbuf
) == -1) {
3714 DEBUG (0,("delete_printer_driver: fail to delete %s!\n", key
));
3715 return WERR_ACCESS_DENIED
;
3719 * now delete any associated files if delete_files == True
3720 * even if this part failes, we return succes because the
3721 * driver doesn not exist any more
3725 delete_driver_files( i
);
3727 DEBUG(5,("delete_printer_driver: [%s] driver delete successful.\n",
3732 /****************************************************************************
3733 ****************************************************************************/
3734 BOOL
get_specific_param_by_index(NT_PRINTER_INFO_LEVEL printer
, uint32 level
, uint32 param_index
,
3735 fstring value
, uint8
**data
, uint32
*type
, uint32
*len
)
3737 /* right now that's enough ! */
3738 NT_PRINTER_PARAM
*param
;
3741 param
=printer
.info_2
->specific
;
3743 while (param
!= NULL
&& i
< param_index
) {
3751 /* exited because it exist */
3753 StrnCpy(value
, param
->value
, sizeof(fstring
)-1);
3754 *data
=(uint8
*)malloc(param
->data_len
*sizeof(uint8
));
3757 ZERO_STRUCTP(*data
);
3758 memcpy(*data
, param
->data
, param
->data_len
);
3759 *len
=param
->data_len
;
3763 /****************************************************************************
3764 ****************************************************************************/
3765 BOOL
get_specific_param(NT_PRINTER_INFO_LEVEL printer
, uint32 level
,
3766 fstring value
, uint8
**data
, uint32
*type
, uint32
*len
)
3768 /* right now that's enough ! */
3769 NT_PRINTER_PARAM
*param
;
3771 DEBUG(10, ("get_specific_param\n"));
3773 param
=printer
.info_2
->specific
;
3775 while (param
!= NULL
)
3777 #if 1 /* JRA - I think this should be case insensitive.... */
3778 if ( strequal(value
, param
->value
)
3780 if ( !strcmp(value
, param
->value
)
3782 && strlen(value
)==strlen(param
->value
))
3790 DEBUGADD(10, ("get_specific_param: found one param\n"));
3791 /* exited because it exist */
3794 *data
=(uint8
*)malloc(param
->data_len
*sizeof(uint8
));
3797 memcpy(*data
, param
->data
, param
->data_len
);
3798 *len
=param
->data_len
;
3800 DEBUGADD(10, ("get_specific_param: exit true\n"));
3803 DEBUGADD(10, ("get_specific_param: exit false\n"));
3807 /****************************************************************************
3808 Store a security desc for a printer.
3809 ****************************************************************************/
3811 WERROR
nt_printing_setsec(const char *printername
, SEC_DESC_BUF
*secdesc_ctr
)
3813 SEC_DESC_BUF
*new_secdesc_ctr
= NULL
;
3814 SEC_DESC_BUF
*old_secdesc_ctr
= NULL
;
3816 TALLOC_CTX
*mem_ctx
= NULL
;
3820 mem_ctx
= talloc_init();
3821 if (mem_ctx
== NULL
)
3824 /* The old owner and group sids of the security descriptor are not
3825 present when new ACEs are added or removed by changing printer
3826 permissions through NT. If they are NULL in the new security
3827 descriptor then copy them over from the old one. */
3829 if (!secdesc_ctr
->sec
->owner_sid
|| !secdesc_ctr
->sec
->grp_sid
) {
3830 DOM_SID
*owner_sid
, *group_sid
;
3831 SEC_ACL
*dacl
, *sacl
;
3832 SEC_DESC
*psd
= NULL
;
3835 nt_printing_getsec(mem_ctx
, printername
, &old_secdesc_ctr
);
3837 /* Pick out correct owner and group sids */
3839 owner_sid
= secdesc_ctr
->sec
->owner_sid
?
3840 secdesc_ctr
->sec
->owner_sid
:
3841 old_secdesc_ctr
->sec
->owner_sid
;
3843 group_sid
= secdesc_ctr
->sec
->grp_sid
?
3844 secdesc_ctr
->sec
->grp_sid
:
3845 old_secdesc_ctr
->sec
->grp_sid
;
3847 dacl
= secdesc_ctr
->sec
->dacl
?
3848 secdesc_ctr
->sec
->dacl
:
3849 old_secdesc_ctr
->sec
->dacl
;
3851 sacl
= secdesc_ctr
->sec
->sacl
?
3852 secdesc_ctr
->sec
->sacl
:
3853 old_secdesc_ctr
->sec
->sacl
;
3855 /* Make a deep copy of the security descriptor */
3857 psd
= make_sec_desc(mem_ctx
, secdesc_ctr
->sec
->revision
,
3858 owner_sid
, group_sid
,
3863 new_secdesc_ctr
= make_sec_desc_buf(mem_ctx
, size
, psd
);
3866 if (!new_secdesc_ctr
) {
3867 new_secdesc_ctr
= secdesc_ctr
;
3870 /* Store the security descriptor in a tdb */
3872 prs_init(&ps
, (uint32
)sec_desc_size(new_secdesc_ctr
->sec
) +
3873 sizeof(SEC_DESC_BUF
), mem_ctx
, MARSHALL
);
3875 if (!sec_io_desc_buf("nt_printing_setsec", &new_secdesc_ctr
,
3877 status
= WERR_BADFUNC
;
3881 slprintf(key
, sizeof(key
)-1, "SECDESC/%s", printername
);
3883 if (tdb_prs_store(tdb_printers
, key
, &ps
)==0) {
3886 DEBUG(1,("Failed to store secdesc for %s\n", printername
));
3887 status
= WERR_BADFUNC
;
3890 /* Free malloc'ed memory */
3896 talloc_destroy(mem_ctx
);
3900 /****************************************************************************
3901 Construct a default security descriptor buffer for a printer.
3902 ****************************************************************************/
3904 static SEC_DESC_BUF
*construct_default_printer_sdb(TALLOC_CTX
*ctx
)
3908 SEC_ACL
*psa
= NULL
;
3909 SEC_DESC_BUF
*sdb
= NULL
;
3910 SEC_DESC
*psd
= NULL
;
3914 /* Create an ACE where Everyone is allowed to print */
3916 init_sec_access(&sa
, PRINTER_ACE_PRINT
);
3917 init_sec_ace(&ace
[0], &global_sid_World
, SEC_ACE_TYPE_ACCESS_ALLOWED
,
3918 sa
, SEC_ACE_FLAG_CONTAINER_INHERIT
);
3920 /* Make the security descriptor owned by the Administrators group
3921 on the PDC of the domain. */
3923 if (secrets_fetch_domain_sid(lp_workgroup(), &owner_sid
)) {
3924 sid_append_rid(&owner_sid
, DOMAIN_USER_RID_ADMIN
);
3927 /* Backup plan - make printer owned by admins.
3928 This should emulate a lanman printer as security
3929 settings can't be changed. */
3931 sid_copy(&owner_sid
, get_global_sam_sid());
3932 sid_append_rid(&owner_sid
, DOMAIN_USER_RID_ADMIN
);
3935 init_sec_access(&sa
, PRINTER_ACE_FULL_CONTROL
);
3936 init_sec_ace(&ace
[1], &owner_sid
, SEC_ACE_TYPE_ACCESS_ALLOWED
,
3937 sa
, SEC_ACE_FLAG_OBJECT_INHERIT
|
3938 SEC_ACE_FLAG_INHERIT_ONLY
);
3940 init_sec_access(&sa
, PRINTER_ACE_FULL_CONTROL
);
3941 init_sec_ace(&ace
[2], &owner_sid
, SEC_ACE_TYPE_ACCESS_ALLOWED
,
3942 sa
, SEC_ACE_FLAG_CONTAINER_INHERIT
);
3944 /* The ACL revision number in rpc_secdesc.h differs from the one
3945 created by NT when setting ACE entries in printer
3946 descriptors. NT4 complains about the property being edited by a
3949 if ((psa
= make_sec_acl(ctx
, NT4_ACL_REVISION
, 3, ace
)) != NULL
) {
3950 psd
= make_sec_desc(ctx
, SEC_DESC_REVISION
,
3952 NULL
, psa
, &sd_size
);
3956 DEBUG(0,("construct_default_printer_sd: Failed to make SEC_DESC.\n"));
3960 sdb
= make_sec_desc_buf(ctx
, sd_size
, psd
);
3962 DEBUG(4,("construct_default_printer_sdb: size = %u.\n",
3963 (unsigned int)sd_size
));
3968 /****************************************************************************
3969 Get a security desc for a printer.
3970 ****************************************************************************/
3972 BOOL
nt_printing_getsec(TALLOC_CTX
*ctx
, const char *printername
, SEC_DESC_BUF
**secdesc_ctr
)
3978 if ((temp
= strchr(printername
+ 2, '\\'))) {
3979 printername
= temp
+ 1;
3982 /* Fetch security descriptor from tdb */
3984 slprintf(key
, sizeof(key
)-1, "SECDESC/%s", printername
);
3986 if (tdb_prs_fetch(tdb_printers
, key
, &ps
, ctx
)!=0 ||
3987 !sec_io_desc_buf("nt_printing_getsec", secdesc_ctr
, &ps
, 1)) {
3989 DEBUG(4,("using default secdesc for %s\n", printername
));
3991 if (!(*secdesc_ctr
= construct_default_printer_sdb(ctx
))) {
3995 /* Save default security descriptor for later */
3997 prs_init(&ps
, (uint32
)sec_desc_size((*secdesc_ctr
)->sec
) +
3998 sizeof(SEC_DESC_BUF
), ctx
, MARSHALL
);
4000 if (sec_io_desc_buf("nt_printing_getsec", secdesc_ctr
, &ps
, 1))
4001 tdb_prs_store(tdb_printers
, key
, &ps
);
4008 /* If security descriptor is owned by S-1-1-0 and winbindd is up,
4009 this security descriptor has been created when winbindd was
4010 down. Take ownership of security descriptor. */
4012 if (sid_equal((*secdesc_ctr
)->sec
->owner_sid
, &global_sid_World
)) {
4015 /* Change sd owner to workgroup administrator */
4017 if (secrets_fetch_domain_sid(lp_workgroup(), &owner_sid
)) {
4018 SEC_DESC_BUF
*new_secdesc_ctr
= NULL
;
4019 SEC_DESC
*psd
= NULL
;
4024 sid_append_rid(&owner_sid
, DOMAIN_USER_RID_ADMIN
);
4026 psd
= make_sec_desc(ctx
, (*secdesc_ctr
)->sec
->revision
,
4028 (*secdesc_ctr
)->sec
->grp_sid
,
4029 (*secdesc_ctr
)->sec
->sacl
,
4030 (*secdesc_ctr
)->sec
->dacl
,
4033 new_secdesc_ctr
= make_sec_desc_buf(ctx
, size
, psd
);
4035 /* Swap with other one */
4037 *secdesc_ctr
= new_secdesc_ctr
;
4041 nt_printing_setsec(printername
, *secdesc_ctr
);
4045 if (DEBUGLEVEL
>= 10) {
4046 SEC_ACL
*the_acl
= (*secdesc_ctr
)->sec
->dacl
;
4049 DEBUG(10, ("secdesc_ctr for %s has %d aces:\n",
4050 printername
, the_acl
->num_aces
));
4052 for (i
= 0; i
< the_acl
->num_aces
; i
++) {
4055 sid_to_string(sid_str
, &the_acl
->ace
[i
].trustee
);
4057 DEBUG(10, ("%s %d %d 0x%08x\n", sid_str
,
4058 the_acl
->ace
[i
].type
, the_acl
->ace
[i
].flags
,
4059 the_acl
->ace
[i
].info
.mask
));
4069 1: level not implemented
4070 2: file doesn't exist
4071 3: can't allocate memory
4072 4: can't free memory
4073 5: non existant struct
4077 A printer and a printer driver are 2 different things.
4078 NT manages them separatelly, Samba does the same.
4079 Why ? Simply because it's easier and it makes sense !
4081 Now explanation: You have 3 printers behind your samba server,
4082 2 of them are the same make and model (laser A and B). But laser B
4083 has an 3000 sheet feeder and laser A doesn't such an option.
4084 Your third printer is an old dot-matrix model for the accounting :-).
4086 If the /usr/local/samba/lib directory (default dir), you will have
4087 5 files to describe all of this.
4089 3 files for the printers (1 by printer):
4092 NTprinter_accounting
4093 2 files for the drivers (1 for the laser and 1 for the dot matrix)
4094 NTdriver_printer model X
4095 NTdriver_printer model Y
4097 jfm: I should use this comment for the text file to explain
4098 same thing for the forms BTW.
4099 Je devrais mettre mes commentaires en francais, ca serait mieux :-)
4103 /* Convert generic access rights to printer object specific access rights.
4104 It turns out that NT4 security descriptors use generic access rights and
4105 NT5 the object specific ones. */
4107 void map_printer_permissions(SEC_DESC
*sd
)
4111 for (i
= 0; sd
->dacl
&& i
< sd
->dacl
->num_aces
; i
++) {
4112 se_map_generic(&sd
->dacl
->ace
[i
].info
.mask
,
4113 &printer_generic_mapping
);
4117 /****************************************************************************
4118 Check a user has permissions to perform the given operation. We use the
4119 permission constants defined in include/rpc_spoolss.h to check the various
4120 actions we perform when checking printer access.
4122 PRINTER_ACCESS_ADMINISTER:
4123 print_queue_pause, print_queue_resume, update_printer_sec,
4124 update_printer, spoolss_addprinterex_level_2,
4125 _spoolss_setprinterdata
4130 JOB_ACCESS_ADMINISTER:
4131 print_job_delete, print_job_pause, print_job_resume,
4134 ****************************************************************************/
4135 BOOL
print_access_check(struct current_user
*user
, int snum
, int access_type
)
4137 SEC_DESC_BUF
*secdesc
= NULL
;
4138 uint32 access_granted
;
4142 TALLOC_CTX
*mem_ctx
= NULL
;
4143 extern struct current_user current_user
;
4145 /* If user is NULL then use the current_user structure */
4148 user
= ¤t_user
;
4150 /* Always allow root or printer admins to do anything */
4152 if (user
->uid
== 0 ||
4153 user_in_list(uidtoname(user
->uid
), lp_printer_admin(snum
))) {
4157 /* Get printer name */
4159 pname
= PRINTERNAME(snum
);
4161 if (!pname
|| !*pname
) {
4166 /* Get printer security descriptor */
4168 if(!(mem_ctx
= talloc_init())) {
4173 nt_printing_getsec(mem_ctx
, pname
, &secdesc
);
4175 if (access_type
== JOB_ACCESS_ADMINISTER
) {
4176 SEC_DESC_BUF
*parent_secdesc
= secdesc
;
4178 /* Create a child security descriptor to check permissions
4179 against. This is because print jobs are child objects
4180 objects of a printer. */
4182 secdesc
= se_create_child_secdesc(mem_ctx
, parent_secdesc
->sec
, False
);
4184 /* Now this is the bit that really confuses me. The access
4185 type needs to be changed from JOB_ACCESS_ADMINISTER to
4186 PRINTER_ACCESS_ADMINISTER for this to work. Something
4187 to do with the child (job) object becoming like a
4190 access_type
= PRINTER_ACCESS_ADMINISTER
;
4195 map_printer_permissions(secdesc
->sec
);
4197 result
= se_access_check(secdesc
->sec
, user
->nt_user_token
, access_type
,
4198 &access_granted
, &status
);
4200 DEBUG(4, ("access check was %s\n", result
? "SUCCESS" : "FAILURE"));
4202 talloc_destroy(mem_ctx
);
4210 /****************************************************************************
4211 Check the time parameters allow a print operation.
4212 *****************************************************************************/
4214 BOOL
print_time_access_check(int snum
)
4216 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
4218 time_t now
= time(NULL
);
4222 if (!W_ERROR_IS_OK(get_a_printer(&printer
, 2, lp_servicename(snum
))))
4225 if (printer
->info_2
->starttime
== 0 && printer
->info_2
->untiltime
== 0)
4229 mins
= (uint32
)t
->tm_hour
*60 + (uint32
)t
->tm_min
;
4231 if (mins
>= printer
->info_2
->starttime
&& mins
<= printer
->info_2
->untiltime
)
4234 free_a_printer(&printer
, 2);
4242 #if 0 /* JERRY - not used */
4243 /****************************************************************************
4244 Attempt to write a default device.
4245 *****************************************************************************/
4247 WERROR
printer_write_default_dev(int snum
, const PRINTER_DEFAULT
*printer_default
)
4249 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
4253 * Don't bother if no default devicemode was sent.
4256 if (printer_default
->devmode_cont
.devmode
== NULL
)
4259 result
= get_a_printer(&printer
, 2, lp_servicename(snum
));
4260 if (!W_ERROR_IS_OK(result
)) return result
;
4263 * Just ignore it if we already have a devmode.
4266 if (printer
->info_2
->devmode
!= NULL
)
4270 * We don't have a devicemode and we're trying to write
4271 * one. Check we have the access needed.
4273 DEBUG(5,("printer_write_default_dev: access: %x\n", printer_default
->access_required
));
4275 if ( (printer_default
->access_required
& PRINTER_ACCESS_ADMINISTER
) !=
4276 PRINTER_ACCESS_ADMINISTER
) {
4277 DEBUG(5,("printer_write_default_dev: invalid request access to update: %x\n", printer_default
->access_required
));
4278 result
= WERR_ACCESS_DENIED
;
4282 if (!print_access_check(NULL
, snum
, PRINTER_ACCESS_ADMINISTER
)) {
4283 DEBUG(5,("printer_write_default_dev: Access denied for printer %s\n",
4284 lp_servicename(snum
) ));
4285 result
= WERR_ACCESS_DENIED
;
4286 /*result = NT_STATUS_NO_PROBLEMO;*/
4290 DEBUG(5,("printer_write_default_dev: updating, check OK.\n"));
4293 * Convert the on the wire devicemode format to the internal one.
4296 if (!convert_devicemode(printer
->info_2
->printername
,
4297 printer_default
->devmode_cont
.devmode
,
4298 &printer
->info_2
->devmode
)) {
4299 result
= WERR_NOMEM
;
4304 * Finally write back to the tdb.
4307 result
= mod_a_printer(*printer
, 2);
4311 free_a_printer(&printer
, 2);