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 const 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
,0);
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
);
326 /*******************************************************************
327 tdb traversal function for counting printers.
328 ********************************************************************/
330 static int traverse_counting_printers(TDB_CONTEXT
*t
, TDB_DATA key
,
331 TDB_DATA data
, void *context
)
333 int *printer_count
= (int*)context
;
335 if (memcmp(PRINTERS_PREFIX
, key
.dptr
, sizeof(PRINTERS_PREFIX
)-1) == 0) {
337 DEBUG(10,("traverse_counting_printers: printer = [%s] printer_count = %d\n", key
.dptr
, *printer_count
));
343 /*******************************************************************
344 Update the spooler global c_setprinter. This variable is initialized
345 when the parent smbd starts with the number of existing printers. It
346 is monotonically increased by the current number of printers *after*
347 each add or delete printer RPC. Only Microsoft knows why... JRR020119
348 ********************************************************************/
350 uint32
update_c_setprinter(BOOL initialize
)
353 int32 printer_count
= 0;
355 tdb_lock_bystring(tdb_printers
, GLOBAL_C_SETPRINTER
,0);
357 /* Traverse the tdb, counting the printers */
358 tdb_traverse(tdb_printers
, traverse_counting_printers
, (void *)&printer_count
);
360 /* If initializing, set c_setprinter to current printers count
361 * otherwise, bump it by the current printer count
364 c_setprinter
= tdb_fetch_int32(tdb_printers
, GLOBAL_C_SETPRINTER
) + printer_count
;
366 c_setprinter
= printer_count
;
368 DEBUG(10,("update_c_setprinter: c_setprinter = %u\n", (unsigned int)c_setprinter
));
369 tdb_store_int32(tdb_printers
, GLOBAL_C_SETPRINTER
, c_setprinter
);
371 tdb_unlock_bystring(tdb_printers
, GLOBAL_C_SETPRINTER
);
373 return (uint32
)c_setprinter
;
376 /*******************************************************************
377 Get the spooler global c_setprinter, accounting for initialization.
378 ********************************************************************/
380 uint32
get_c_setprinter(void)
382 int32 c_setprinter
= tdb_fetch_int32(tdb_printers
, GLOBAL_C_SETPRINTER
);
384 if (c_setprinter
== (int32
)-1)
385 c_setprinter
= update_c_setprinter(True
);
387 DEBUG(10,("get_c_setprinter: c_setprinter = %d\n", c_setprinter
));
389 return (uint32
)c_setprinter
;
392 /****************************************************************************
393 Get builtin form struct list.
394 ****************************************************************************/
396 int get_builtin_ntforms(nt_forms_struct
**list
)
398 *list
= (nt_forms_struct
*)memdup(&default_forms
[0], sizeof(default_forms
));
399 return sizeof(default_forms
) / sizeof(default_forms
[0]);
402 /****************************************************************************
403 get a builtin form struct
404 ****************************************************************************/
406 BOOL
get_a_builtin_ntform(UNISTR2
*uni_formname
,nt_forms_struct
*form
)
410 unistr2_to_dos(form_name
, uni_formname
, sizeof(form_name
)-1);
411 DEBUGADD(6,("Looking for builtin form %s \n", form_name
));
412 count
= sizeof(default_forms
) / sizeof(default_forms
[0]);
413 for (i
=0;i
<count
;i
++) {
414 if (strequal(form_name
,default_forms
[i
].name
)) {
415 DEBUGADD(6,("Found builtin form %s \n", form_name
));
416 memcpy(form
,&default_forms
[i
],sizeof(*form
));
424 /****************************************************************************
425 get a form struct list
426 ****************************************************************************/
427 int get_ntforms(nt_forms_struct
**list
)
429 TDB_DATA kbuf
, newkey
, dbuf
;
431 nt_forms_struct form
;
436 for (kbuf
= tdb_firstkey(tdb_forms
);
438 newkey
= tdb_nextkey(tdb_forms
, kbuf
), safe_free(kbuf
.dptr
), kbuf
=newkey
) {
439 if (strncmp(kbuf
.dptr
, FORMS_PREFIX
, strlen(FORMS_PREFIX
)) != 0) continue;
441 dbuf
= tdb_fetch(tdb_forms
, kbuf
);
442 if (!dbuf
.dptr
) continue;
444 fstrcpy(form
.name
, kbuf
.dptr
+strlen(FORMS_PREFIX
));
445 ret
= tdb_unpack(dbuf
.dptr
, dbuf
.dsize
, "dddddddd",
446 &i
, &form
.flag
, &form
.width
, &form
.length
, &form
.left
,
447 &form
.top
, &form
.right
, &form
.bottom
);
448 SAFE_FREE(dbuf
.dptr
);
449 if (ret
!= dbuf
.dsize
) continue;
451 tl
= Realloc(*list
, sizeof(nt_forms_struct
)*(n
+1));
453 DEBUG(0,("get_ntforms: Realloc fail.\n"));
465 /****************************************************************************
466 write a form struct list
467 ****************************************************************************/
468 int write_ntforms(nt_forms_struct
**list
, int number
)
475 for (i
=0;i
<number
;i
++) {
476 /* save index, so list is rebuilt in correct order */
477 len
= tdb_pack(buf
, sizeof(buf
), "dddddddd",
478 i
, (*list
)[i
].flag
, (*list
)[i
].width
, (*list
)[i
].length
,
479 (*list
)[i
].left
, (*list
)[i
].top
, (*list
)[i
].right
,
481 if (len
> sizeof(buf
)) break;
482 slprintf(key
, sizeof(key
)-1, "%s%s", FORMS_PREFIX
, (*list
)[i
].name
);
483 dos_to_unix(key
); /* Convert key to unix-codepage */
484 kbuf
.dsize
= strlen(key
)+1;
488 if (tdb_store(tdb_forms
, kbuf
, dbuf
, TDB_REPLACE
) != 0) break;
494 /****************************************************************************
495 add a form struct at the end of the list
496 ****************************************************************************/
497 BOOL
add_a_form(nt_forms_struct
**list
, const FORM
*form
, int *count
)
505 * NT tries to add forms even when
506 * they are already in the base
507 * only update the values if already present
512 unistr2_to_dos(form_name
, &form
->name
, sizeof(form_name
)-1);
513 for (n
=0; n
<*count
; n
++) {
514 if (!strncmp((*list
)[n
].name
, form_name
, strlen(form_name
))) {
515 DEBUG(103, ("NT workaround, [%s] already exists\n", form_name
));
522 if((tl
=Realloc(*list
, (n
+1)*sizeof(nt_forms_struct
))) == NULL
) {
523 DEBUG(0,("add_a_form: failed to enlarge forms list!\n"));
527 unistr2_to_dos((*list
)[n
].name
, &form
->name
, sizeof((*list
)[n
].name
)-1);
531 (*list
)[n
].flag
=form
->flags
;
532 (*list
)[n
].width
=form
->size_x
;
533 (*list
)[n
].length
=form
->size_y
;
534 (*list
)[n
].left
=form
->left
;
535 (*list
)[n
].top
=form
->top
;
536 (*list
)[n
].right
=form
->right
;
537 (*list
)[n
].bottom
=form
->bottom
;
542 /****************************************************************************
543 delete a named form struct
544 ****************************************************************************/
545 BOOL
delete_a_form(nt_forms_struct
**list
, UNISTR2
*del_name
, int *count
, WERROR
*ret
)
554 unistr2_to_dos(form_name
, del_name
, sizeof(form_name
)-1);
556 for (n
=0; n
<*count
; n
++) {
557 if (!strncmp((*list
)[n
].name
, form_name
, strlen(form_name
))) {
558 DEBUG(103, ("delete_a_form, [%s] in list\n", form_name
));
564 DEBUG(10,("delete_a_form, [%s] not found\n", form_name
));
565 *ret
= WERR_INVALID_PARAM
;
569 slprintf(key
, sizeof(key
)-1, "%s%s", FORMS_PREFIX
, (*list
)[n
].name
);
570 dos_to_unix(key
); /* Convert key to unix-codepage */
571 kbuf
.dsize
= strlen(key
)+1;
573 if (tdb_delete(tdb_forms
, kbuf
) != 0) {
581 /****************************************************************************
583 ****************************************************************************/
584 void update_a_form(nt_forms_struct
**list
, const FORM
*form
, int count
)
588 unistr2_to_dos(form_name
, &(form
->name
), sizeof(form_name
)-1);
590 DEBUG(106, ("[%s]\n", form_name
));
591 for (n
=0; n
<count
; n
++)
593 DEBUGADD(106, ("n [%d]:[%s]\n", n
, (*list
)[n
].name
));
594 if (!strncmp((*list
)[n
].name
, form_name
, strlen(form_name
)))
598 if (n
==count
) return;
600 (*list
)[n
].flag
=form
->flags
;
601 (*list
)[n
].width
=form
->size_x
;
602 (*list
)[n
].length
=form
->size_y
;
603 (*list
)[n
].left
=form
->left
;
604 (*list
)[n
].top
=form
->top
;
605 (*list
)[n
].right
=form
->right
;
606 (*list
)[n
].bottom
=form
->bottom
;
609 /****************************************************************************
610 get the nt drivers list
612 traverse the database and look-up the matching names
613 ****************************************************************************/
614 int get_ntdrivers(fstring
**list
, char *architecture
, uint32 version
)
620 TDB_DATA kbuf
, newkey
;
622 get_short_archi(short_archi
, architecture
);
623 slprintf(key
, sizeof(key
)-1, "%s%s/%d/", DRIVERS_PREFIX
, short_archi
, version
);
625 for (kbuf
= tdb_firstkey(tdb_drivers
);
627 newkey
= tdb_nextkey(tdb_drivers
, kbuf
), safe_free(kbuf
.dptr
), kbuf
=newkey
) {
628 if (strncmp(kbuf
.dptr
, key
, strlen(key
)) != 0) continue;
630 if((fl
= Realloc(*list
, sizeof(fstring
)*(total
+1))) == NULL
) {
631 DEBUG(0,("get_ntdrivers: failed to enlarge list!\n"));
636 fstrcpy((*list
)[total
], kbuf
.dptr
+strlen(key
));
643 /****************************************************************************
644 function to do the mapping between the long architecture name and
646 ****************************************************************************/
648 BOOL
get_short_archi(char *short_archi
, const char *long_archi
)
651 const char *long_archi
;
652 const char *short_archi
;
655 struct table archi_table
[]=
657 {"Windows 4.0", "WIN40" },
658 {"Windows NT x86", "W32X86" },
659 {"Windows NT R4000", "W32MIPS" },
660 {"Windows NT Alpha_AXP", "W32ALPHA" },
661 {"Windows NT PowerPC", "W32PPC" },
667 DEBUG(107,("Getting architecture dependant directory\n"));
669 if (long_archi
== NULL
) {
670 DEBUGADD(107,("Bad long_archi param.!\n"));
676 } while ( (archi_table
[i
].long_archi
!=NULL
) &&
677 StrCaseCmp(long_archi
, archi_table
[i
].long_archi
) );
679 if (archi_table
[i
].long_archi
==NULL
) {
680 DEBUGADD(107,("Unknown architecture [%s] !\n", long_archi
));
684 StrnCpy (short_archi
, archi_table
[i
].short_archi
, strlen(archi_table
[i
].short_archi
));
686 DEBUGADD(108,("index: [%d]\n", i
));
687 DEBUGADD(108,("long architecture: [%s]\n", long_archi
));
688 DEBUGADD(108,("short architecture: [%s]\n", short_archi
));
693 /****************************************************************************
694 Version information in Microsoft files is held in a VS_VERSION_INFO structure.
695 There are two case to be covered here: PE (Portable Executable) and NE (New
696 Executable) files. Both files support the same INFO structure, but PE files
697 store the signature in unicode, and NE files store it as !unicode.
698 returns -1 on error, 1 on version info found, and 0 on no version info found.
699 ****************************************************************************/
701 static int get_file_version(files_struct
*fsp
, char *fname
,uint32
*major
, uint32
*minor
)
707 if ((buf
=malloc(PE_HEADER_SIZE
)) == NULL
) {
708 DEBUG(0,("get_file_version: PE file [%s] PE Header malloc failed bytes = %d\n",
709 fname
, PE_HEADER_SIZE
));
713 /* Note: DOS_HEADER_SIZE < malloc'ed PE_HEADER_SIZE */
714 if ((byte_count
= vfs_read_data(fsp
, buf
, DOS_HEADER_SIZE
)) < DOS_HEADER_SIZE
) {
715 DEBUG(3,("get_file_version: File [%s] DOS header too short, bytes read = %d\n",
717 goto no_version_info
;
720 /* Is this really a DOS header? */
721 if (SVAL(buf
,DOS_HEADER_MAGIC_OFFSET
) != DOS_HEADER_MAGIC
) {
722 DEBUG(6,("get_file_version: File [%s] bad DOS magic = 0x%x\n",
723 fname
, SVAL(buf
,DOS_HEADER_MAGIC_OFFSET
)));
724 goto no_version_info
;
727 /* Skip OEM header (if any) and the DOS stub to start of Windows header */
728 if (fsp
->conn
->vfs_ops
.lseek(fsp
, fsp
->fd
, SVAL(buf
,DOS_HEADER_LFANEW_OFFSET
), SEEK_SET
) == (SMB_OFF_T
)-1) {
729 DEBUG(3,("get_file_version: File [%s] too short, errno = %d\n",
731 /* Assume this isn't an error... the file just looks sort of like a PE/NE file */
732 goto no_version_info
;
735 if ((byte_count
= vfs_read_data(fsp
, buf
, PE_HEADER_SIZE
)) < PE_HEADER_SIZE
) {
736 DEBUG(3,("get_file_version: File [%s] Windows header too short, bytes read = %d\n",
738 /* Assume this isn't an error... the file just looks sort of like a PE/NE file */
739 goto no_version_info
;
742 /* The header may be a PE (Portable Executable) or an NE (New Executable) */
743 if (IVAL(buf
,PE_HEADER_SIGNATURE_OFFSET
) == PE_HEADER_SIGNATURE
) {
745 int section_table_bytes
;
747 if (SVAL(buf
,PE_HEADER_MACHINE_OFFSET
) != PE_HEADER_MACHINE_I386
) {
748 DEBUG(3,("get_file_version: PE file [%s] wrong machine = 0x%x\n",
749 fname
, SVAL(buf
,PE_HEADER_MACHINE_OFFSET
)));
750 /* At this point, we assume the file is in error. It still could be somthing
751 * else besides a PE file, but it unlikely at this point.
756 /* get the section table */
757 num_sections
= SVAL(buf
,PE_HEADER_NUMBER_OF_SECTIONS
);
758 section_table_bytes
= num_sections
* PE_HEADER_SECT_HEADER_SIZE
;
760 if ((buf
=malloc(section_table_bytes
)) == NULL
) {
761 DEBUG(0,("get_file_version: PE file [%s] section table malloc failed bytes = %d\n",
762 fname
, section_table_bytes
));
766 if ((byte_count
= vfs_read_data(fsp
, buf
, section_table_bytes
)) < section_table_bytes
) {
767 DEBUG(3,("get_file_version: PE file [%s] Section header too short, bytes read = %d\n",
772 /* Iterate the section table looking for the resource section ".rsrc" */
773 for (i
= 0; i
< num_sections
; i
++) {
774 int sec_offset
= i
* PE_HEADER_SECT_HEADER_SIZE
;
776 if (strcmp(".rsrc", &buf
[sec_offset
+PE_HEADER_SECT_NAME_OFFSET
]) == 0) {
777 int section_pos
= IVAL(buf
,sec_offset
+PE_HEADER_SECT_PTR_DATA_OFFSET
);
778 int section_bytes
= IVAL(buf
,sec_offset
+PE_HEADER_SECT_SIZE_DATA_OFFSET
);
781 if ((buf
=malloc(section_bytes
)) == NULL
) {
782 DEBUG(0,("get_file_version: PE file [%s] version malloc failed bytes = %d\n",
783 fname
, section_bytes
));
787 /* Seek to the start of the .rsrc section info */
788 if (fsp
->conn
->vfs_ops
.lseek(fsp
, fsp
->fd
, section_pos
, SEEK_SET
) == (SMB_OFF_T
)-1) {
789 DEBUG(3,("get_file_version: PE file [%s] too short for section info, errno = %d\n",
794 if ((byte_count
= vfs_read_data(fsp
, buf
, section_bytes
)) < section_bytes
) {
795 DEBUG(3,("get_file_version: PE file [%s] .rsrc section too short, bytes read = %d\n",
800 for (i
=0; i
<section_bytes
-VS_VERSION_INFO_UNICODE_SIZE
; i
++) {
801 /* Scan for 1st 3 unicoded bytes followed by word aligned magic value */
802 if (buf
[i
] == 'V' && buf
[i
+1] == '\0' && buf
[i
+2] == 'S') {
803 /* Align to next long address */
804 int pos
= (i
+ sizeof(VS_SIGNATURE
)*2 + 3) & 0xfffffffc;
806 if (IVAL(buf
,pos
) == VS_MAGIC_VALUE
) {
807 *major
= IVAL(buf
,pos
+VS_MAJOR_OFFSET
);
808 *minor
= IVAL(buf
,pos
+VS_MINOR_OFFSET
);
810 DEBUG(6,("get_file_version: PE file [%s] Version = %08x:%08x (%d.%d.%d.%d)\n",
811 fname
, *major
, *minor
,
812 (*major
>>16)&0xffff, *major
&0xffff,
813 (*minor
>>16)&0xffff, *minor
&0xffff));
822 /* Version info not found, fall back to origin date/time */
823 DEBUG(10,("get_file_version: PE file [%s] has no version info\n", fname
));
827 } else if (SVAL(buf
,NE_HEADER_SIGNATURE_OFFSET
) == NE_HEADER_SIGNATURE
) {
828 if (CVAL(buf
,NE_HEADER_TARGET_OS_OFFSET
) != NE_HEADER_TARGOS_WIN
) {
829 DEBUG(3,("get_file_version: NE file [%s] wrong target OS = 0x%x\n",
830 fname
, CVAL(buf
,NE_HEADER_TARGET_OS_OFFSET
)));
831 /* At this point, we assume the file is in error. It still could be somthing
832 * else besides a NE file, but it unlikely at this point. */
836 /* Allocate a bit more space to speed up things */
838 if ((buf
=malloc(VS_NE_BUF_SIZE
)) == NULL
) {
839 DEBUG(0,("get_file_version: NE file [%s] malloc failed bytes = %d\n",
840 fname
, PE_HEADER_SIZE
));
844 /* This is a HACK! I got tired of trying to sort through the messy
845 * 'NE' file format. If anyone wants to clean this up please have at
846 * it, but this works. 'NE' files will eventually fade away. JRR */
847 while((byte_count
= vfs_read_data(fsp
, buf
, VS_NE_BUF_SIZE
)) > 0) {
848 /* Cover case that should not occur in a well formed 'NE' .dll file */
849 if (byte_count
-VS_VERSION_INFO_SIZE
<= 0) break;
851 for(i
=0; i
<byte_count
; i
++) {
852 /* Fast skip past data that can't possibly match */
853 if (buf
[i
] != 'V') continue;
855 /* Potential match data crosses buf boundry, move it to beginning
856 * of buf, and fill the buf with as much as it will hold. */
857 if (i
>byte_count
-VS_VERSION_INFO_SIZE
) {
860 memcpy(buf
, &buf
[i
], byte_count
-i
);
861 if ((bc
= vfs_read_data(fsp
, &buf
[byte_count
-i
], VS_NE_BUF_SIZE
-
862 (byte_count
-i
))) < 0) {
864 DEBUG(0,("get_file_version: NE file [%s] Read error, errno=%d\n",
869 byte_count
= bc
+ (byte_count
- i
);
870 if (byte_count
<VS_VERSION_INFO_SIZE
) break;
875 /* Check that the full signature string and the magic number that
876 * follows exist (not a perfect solution, but the chances that this
877 * occurs in code is, well, remote. Yes I know I'm comparing the 'V'
878 * twice, as it is simpler to read the code. */
879 if (strcmp(&buf
[i
], VS_SIGNATURE
) == 0) {
880 /* Compute skip alignment to next long address */
881 int skip
= -(fsp
->conn
->vfs_ops
.lseek(fsp
, fsp
->fd
, 0, SEEK_CUR
) - (byte_count
- i
) +
882 sizeof(VS_SIGNATURE
)) & 3;
883 if (IVAL(buf
,i
+sizeof(VS_SIGNATURE
)+skip
) != 0xfeef04bd) continue;
885 *major
= IVAL(buf
,i
+sizeof(VS_SIGNATURE
)+skip
+VS_MAJOR_OFFSET
);
886 *minor
= IVAL(buf
,i
+sizeof(VS_SIGNATURE
)+skip
+VS_MINOR_OFFSET
);
887 DEBUG(6,("get_file_version: NE file [%s] Version = %08x:%08x (%d.%d.%d.%d)\n",
888 fname
, *major
, *minor
,
889 (*major
>>16)&0xffff, *major
&0xffff,
890 (*minor
>>16)&0xffff, *minor
&0xffff));
897 /* Version info not found, fall back to origin date/time */
898 DEBUG(0,("get_file_version: NE file [%s] Version info not found\n", fname
));
903 /* Assume this isn't an error... the file just looks sort of like a PE/NE file */
904 DEBUG(3,("get_file_version: File [%s] unknown file format, signature = 0x%x\n",
905 fname
, IVAL(buf
,PE_HEADER_SIGNATURE_OFFSET
)));
916 /****************************************************************************
917 Drivers for Microsoft systems contain multiple files. Often, multiple drivers
918 share one or more files. During the MS installation process files are checked
919 to insure that only a newer version of a shared file is installed over an
920 older version. There are several possibilities for this comparison. If there
921 is no previous version, the new one is newer (obviously). If either file is
922 missing the version info structure, compare the creation date (on Unix use
923 the modification date). Otherwise chose the numerically larger version number.
924 ****************************************************************************/
925 static int file_version_is_newer(connection_struct
*conn
, fstring new_file
,
928 BOOL use_version
= True
;
933 time_t new_create_time
;
937 time_t old_create_time
;
941 files_struct
*fsp
= NULL
;
943 SMB_STRUCT_STAT stat_buf
;
947 ZERO_STRUCT(stat_buf
);
948 new_create_time
= (time_t)0;
949 old_create_time
= (time_t)0;
951 /* Get file version info (if available) for previous file (if it exists) */
952 pstrcpy(filepath
, old_file
);
954 unix_convert(filepath
,conn
,NULL
,&bad_path
,&stat_buf
);
956 fsp
= open_file_shared(conn
, filepath
, &stat_buf
,
957 SET_OPEN_MODE(DOS_OPEN_RDONLY
),
958 (FILE_FAIL_IF_NOT_EXIST
|FILE_EXISTS_OPEN
),
959 0, 0, &access_mode
, &action
);
961 /* Old file not found, so by definition new file is in fact newer */
962 DEBUG(10,("file_version_is_newer: Can't open old file [%s], errno = %d\n",
967 int ret
= get_file_version(fsp
, old_file
, &old_major
, &old_minor
);
968 if (ret
== -1) goto error_exit
;
971 DEBUG(6,("file_version_is_newer: Version info not found [%s], use mod time\n",
975 if (fsp
->conn
->vfs_ops
.fstat(fsp
, fsp
->fd
, &st
) == -1) goto error_exit
;
976 old_create_time
= st
.st_mtime
;
977 DEBUGADD(6,("file_version_is_newer: mod time = %ld sec\n", old_create_time
));
979 close_file(fsp
, True
);
981 /* Get file version info (if available) for new file */
982 pstrcpy(filepath
, new_file
);
983 unix_convert(filepath
,conn
,NULL
,&bad_path
,&stat_buf
);
985 fsp
= open_file_shared(conn
, filepath
, &stat_buf
,
986 SET_OPEN_MODE(DOS_OPEN_RDONLY
),
987 (FILE_FAIL_IF_NOT_EXIST
|FILE_EXISTS_OPEN
),
988 0, 0, &access_mode
, &action
);
990 /* New file not found, this shouldn't occur if the caller did its job */
991 DEBUG(3,("file_version_is_newer: Can't open new file [%s], errno = %d\n",
996 int ret
= get_file_version(fsp
, new_file
, &new_major
, &new_minor
);
997 if (ret
== -1) goto error_exit
;
1000 DEBUG(6,("file_version_is_newer: Version info not found [%s], use mod time\n",
1002 use_version
= False
;
1004 if (fsp
->conn
->vfs_ops
.fstat(fsp
, fsp
->fd
, &st
) == -1) goto error_exit
;
1005 new_create_time
= st
.st_mtime
;
1006 DEBUGADD(6,("file_version_is_newer: mod time = %ld sec\n", new_create_time
));
1008 close_file(fsp
, True
);
1010 if (use_version
&& (new_major
!= old_major
|| new_minor
!= old_minor
)) {
1011 /* Compare versions and choose the larger version number */
1012 if (new_major
> old_major
||
1013 (new_major
== old_major
&& new_minor
> old_minor
)) {
1015 DEBUG(6,("file_version_is_newer: Replacing [%s] with [%s]\n", old_file
, new_file
));
1019 DEBUG(6,("file_version_is_newer: Leaving [%s] unchanged\n", old_file
));
1024 /* Compare modification time/dates and choose the newest time/date */
1025 if (new_create_time
> old_create_time
) {
1026 DEBUG(6,("file_version_is_newer: Replacing [%s] with [%s]\n", old_file
, new_file
));
1030 DEBUG(6,("file_version_is_newer: Leaving [%s] unchanged\n", old_file
));
1037 close_file(fsp
, True
);
1041 /****************************************************************************
1042 Determine the correct cVersion associated with an architecture and driver
1043 ****************************************************************************/
1044 static uint32
get_correct_cversion(fstring architecture
, fstring driverpath_in
,
1045 struct current_user
*user
, WERROR
*perr
)
1055 files_struct
*fsp
= NULL
;
1059 struct passwd
*pass
;
1060 connection_struct
*conn
;
1064 *perr
= WERR_INVALID_PARAM
;
1066 /* If architecture is Windows 95/98/ME, the version is always 0. */
1067 if (strcmp(architecture
, "WIN40") == 0) {
1068 DEBUG(10,("get_correct_cversion: Driver is Win9x, cversion = 0\n"));
1074 pass
= sys_getpwuid(user
->uid
);
1076 DEBUG(0,("get_correct_cversion: Unable to get passwd entry for uid %u\n",
1077 (unsigned int)user
->uid
));
1079 *perr
= WERR_ACCESS_DENIED
;
1084 * Connect to the print$ share under the same account as the user connected
1085 * to the rpc pipe. Note we must still be root to do this.
1088 fstrcpy(user_name
, pass
->pw_name
);
1089 DEBUG(10,("get_correct_cversion: uid %d -> user %s\n", (int)user
->uid
, user_name
));
1091 /* Null password is ok - we are already an authenticated user... */
1094 fstrcpy(sharename
, "print$");
1095 conn
= make_connection(sharename
, user_name
, null_pw
, 0, dev
, user
->vuid
, &ecode
);
1099 DEBUG(0,("get_correct_cversion: Unable to connect\n"));
1100 *perr
= W_ERROR(ecode
);
1104 /* We are temporarily becoming the connection user. */
1105 if (!become_user(conn
, conn
->vuid
)) {
1106 DEBUG(0,("get_correct_cversion: Can't become user!\n"));
1107 *perr
= WERR_ACCESS_DENIED
;
1111 /* Open the driver file (Portable Executable format) and determine the
1112 * deriver the cversion. */
1113 slprintf(driverpath
, sizeof(driverpath
)-1, "%s/%s", architecture
, driverpath_in
);
1115 unix_convert(driverpath
,conn
,NULL
,&bad_path
,&st
);
1117 fsp
= open_file_shared(conn
, driverpath
, &st
,
1118 SET_OPEN_MODE(DOS_OPEN_RDONLY
),
1119 (FILE_FAIL_IF_NOT_EXIST
|FILE_EXISTS_OPEN
),
1120 0, 0, &access_mode
, &action
);
1122 DEBUG(3,("get_correct_cversion: Can't open file [%s], errno = %d\n",
1123 driverpath
, errno
));
1124 *perr
= WERR_ACCESS_DENIED
;
1130 int ret
= get_file_version(fsp
, driverpath
, &major
, &minor
);
1131 if (ret
== -1) goto error_exit
;
1134 DEBUG(6,("get_correct_cversion: Version info not found [%s]\n", driverpath
));
1139 * This is a Microsoft'ism. See references in MSDN to VER_FILEVERSION
1140 * for more details. Version in this case is not just the version of the
1141 * file, but the version in the sense of kernal mode (2) vs. user mode
1142 * (3) drivers. Other bits of the version fields are the version info.
1145 cversion
= major
& 0x0000ffff;
1147 case 2: /* WinNT drivers */
1148 case 3: /* Win2K drivers */
1152 DEBUG(6,("get_correct_cversion: cversion invalid [%s] cversion = %d\n",
1153 driverpath
, cversion
));
1157 DEBUG(10,("get_correct_cversion: Version info found [%s] major = 0x%x minor = 0x%x\n",
1158 driverpath
, major
, minor
));
1161 DEBUG(10,("get_correct_cversion: Driver file [%s] cversion = %d\n",
1162 driverpath
, cversion
));
1164 close_file(fsp
, True
);
1165 close_cnum(conn
, user
->vuid
);
1174 close_file(fsp
, True
);
1176 close_cnum(conn
, user
->vuid
);
1181 /****************************************************************************
1182 ****************************************************************************/
1183 static WERROR
clean_up_driver_struct_level_3(NT_PRINTER_DRIVER_INFO_LEVEL_3
*driver
,
1184 struct current_user
*user
)
1186 fstring architecture
;
1192 /* clean up the driver name.
1193 * we can get .\driver.dll
1194 * or worse c:\windows\system\driver.dll !
1196 /* using an intermediate string to not have overlaping memcpy()'s */
1197 if ((p
= strrchr(driver
->driverpath
,'\\')) != NULL
) {
1198 fstrcpy(new_name
, p
+1);
1199 fstrcpy(driver
->driverpath
, new_name
);
1202 if ((p
= strrchr(driver
->datafile
,'\\')) != NULL
) {
1203 fstrcpy(new_name
, p
+1);
1204 fstrcpy(driver
->datafile
, new_name
);
1207 if ((p
= strrchr(driver
->configfile
,'\\')) != NULL
) {
1208 fstrcpy(new_name
, p
+1);
1209 fstrcpy(driver
->configfile
, new_name
);
1212 if ((p
= strrchr(driver
->helpfile
,'\\')) != NULL
) {
1213 fstrcpy(new_name
, p
+1);
1214 fstrcpy(driver
->helpfile
, new_name
);
1217 if (driver
->dependentfiles
) {
1218 for (i
=0; *driver
->dependentfiles
[i
]; i
++) {
1219 if ((p
= strrchr(driver
->dependentfiles
[i
],'\\')) != NULL
) {
1220 fstrcpy(new_name
, p
+1);
1221 fstrcpy(driver
->dependentfiles
[i
], new_name
);
1226 get_short_archi(architecture
, driver
->environment
);
1228 /* jfm:7/16/2000 the client always sends the cversion=0.
1229 * The server should check which version the driver is by reading
1230 * the PE header of driver->driverpath.
1232 * For Windows 95/98 the version is 0 (so the value sent is correct)
1233 * For Windows NT (the architecture doesn't matter)
1234 * NT 3.1: cversion=0
1235 * NT 3.5/3.51: cversion=1
1239 if ((driver
->cversion
= get_correct_cversion( architecture
,
1240 driver
->driverpath
, user
, &err
)) == -1)
1246 /****************************************************************************
1247 ****************************************************************************/
1248 static WERROR
clean_up_driver_struct_level_6(NT_PRINTER_DRIVER_INFO_LEVEL_6
*driver
,
1249 struct current_user
*user
)
1251 fstring architecture
;
1257 /* clean up the driver name.
1258 * we can get .\driver.dll
1259 * or worse c:\windows\system\driver.dll !
1261 /* using an intermediate string to not have overlaping memcpy()'s */
1262 if ((p
= strrchr(driver
->driverpath
,'\\')) != NULL
) {
1263 fstrcpy(new_name
, p
+1);
1264 fstrcpy(driver
->driverpath
, new_name
);
1267 if ((p
= strrchr(driver
->datafile
,'\\')) != NULL
) {
1268 fstrcpy(new_name
, p
+1);
1269 fstrcpy(driver
->datafile
, new_name
);
1272 if ((p
= strrchr(driver
->configfile
,'\\')) != NULL
) {
1273 fstrcpy(new_name
, p
+1);
1274 fstrcpy(driver
->configfile
, new_name
);
1277 if ((p
= strrchr(driver
->helpfile
,'\\')) != NULL
) {
1278 fstrcpy(new_name
, p
+1);
1279 fstrcpy(driver
->helpfile
, new_name
);
1282 if (driver
->dependentfiles
) {
1283 for (i
=0; *driver
->dependentfiles
[i
]; i
++) {
1284 if ((p
= strrchr(driver
->dependentfiles
[i
],'\\')) != NULL
) {
1285 fstrcpy(new_name
, p
+1);
1286 fstrcpy(driver
->dependentfiles
[i
], new_name
);
1291 get_short_archi(architecture
, driver
->environment
);
1293 /* jfm:7/16/2000 the client always sends the cversion=0.
1294 * The server should check which version the driver is by reading
1295 * the PE header of driver->driverpath.
1297 * For Windows 95/98 the version is 0 (so the value sent is correct)
1298 * For Windows NT (the architecture doesn't matter)
1299 * NT 3.1: cversion=0
1300 * NT 3.5/3.51: cversion=1
1304 if ((driver
->version
= get_correct_cversion(architecture
,
1305 driver
->driverpath
, user
, &err
)) == -1)
1311 /****************************************************************************
1312 ****************************************************************************/
1313 WERROR
clean_up_driver_struct(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract
,
1314 uint32 level
, struct current_user
*user
)
1319 NT_PRINTER_DRIVER_INFO_LEVEL_3
*driver
;
1320 driver
=driver_abstract
.info_3
;
1321 return clean_up_driver_struct_level_3(driver
, user
);
1325 NT_PRINTER_DRIVER_INFO_LEVEL_6
*driver
;
1326 driver
=driver_abstract
.info_6
;
1327 return clean_up_driver_struct_level_6(driver
, user
);
1330 return WERR_INVALID_PARAM
;
1334 /****************************************************************************
1335 This function sucks and should be replaced. JRA.
1336 ****************************************************************************/
1338 static void convert_level_6_to_level3(NT_PRINTER_DRIVER_INFO_LEVEL_3
*dst
, NT_PRINTER_DRIVER_INFO_LEVEL_6
*src
)
1340 dst
->cversion
= src
->version
;
1342 fstrcpy( dst
->name
, src
->name
);
1343 fstrcpy( dst
->environment
, src
->environment
);
1344 fstrcpy( dst
->driverpath
, src
->driverpath
);
1345 fstrcpy( dst
->datafile
, src
->datafile
);
1346 fstrcpy( dst
->configfile
, src
->configfile
);
1347 fstrcpy( dst
->helpfile
, src
->helpfile
);
1348 fstrcpy( dst
->monitorname
, src
->monitorname
);
1349 fstrcpy( dst
->defaultdatatype
, src
->defaultdatatype
);
1350 dst
->dependentfiles
= src
->dependentfiles
;
1353 #if 0 /* Debugging function */
1355 static char* ffmt(unsigned char *c
){
1357 static char ffmt_str
[17];
1359 for (i
=0; i
<16; i
++) {
1360 if ((c
[i
] < ' ') || (c
[i
] > '~'))
1371 /****************************************************************************
1372 ****************************************************************************/
1373 BOOL
move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract
, uint32 level
,
1374 struct current_user
*user
, WERROR
*perr
)
1376 NT_PRINTER_DRIVER_INFO_LEVEL_3
*driver
;
1377 NT_PRINTER_DRIVER_INFO_LEVEL_3 converted_driver
;
1378 fstring architecture
;
1386 connection_struct
*conn
;
1389 struct passwd
*pass
;
1394 memset(inbuf
, '\0', sizeof(inbuf
));
1395 memset(outbuf
, '\0', sizeof(outbuf
));
1399 driver
=driver_abstract
.info_3
;
1400 else if (level
==6) {
1401 convert_level_6_to_level3(&converted_driver
, driver_abstract
.info_6
);
1402 driver
= &converted_driver
;
1404 DEBUG(0,("move_driver_to_download_area: Unknown info level (%u)\n", (unsigned int)level
));
1408 get_short_archi(architecture
, driver
->environment
);
1411 pass
= sys_getpwuid(user
->uid
);
1413 DEBUG(0,("move_driver_to_download_area: Unable to get passwd entry for uid %u\n",
1414 (unsigned int)user
->uid
));
1420 * Connect to the print$ share under the same account as the user connected to the rpc pipe.
1421 * Note we must be root to do this.
1424 fstrcpy(user_name
, pass
->pw_name
);
1425 DEBUG(10,("move_driver_to_download_area: uid %d -> user %s\n", (int)user
->uid
, user_name
));
1427 /* Null password is ok - we are already an authenticated user... */
1430 fstrcpy(sharename
, "print$");
1431 conn
= make_connection(sharename
, user_name
, null_pw
, 0, dev
, user
->vuid
, &ecode
);
1435 DEBUG(0,("move_driver_to_download_area: Unable to connect\n"));
1436 *perr
= W_ERROR(ecode
);
1441 * Save who we are - we are temporarily becoming the connection user.
1444 if (!become_user(conn
, conn
->vuid
)) {
1445 DEBUG(0,("move_driver_to_download_area: Can't become user %s\n", user_name
));
1450 * make the directories version and version\driver_name
1451 * under the architecture directory.
1453 DEBUG(5,("Creating first directory\n"));
1454 slprintf(new_dir
, sizeof(new_dir
)-1, "%s/%d", architecture
, driver
->cversion
);
1455 mkdir_internal(conn
, new_dir
);
1457 /* For each driver file, archi\filexxx.yyy, if there is a duplicate file
1458 * listed for this driver which has already been moved, skip it (note:
1459 * drivers may list the same file name several times. Then check if the
1460 * file already exists in archi\cversion\, if so, check that the version
1461 * info (or time stamps if version info is unavailable) is newer (or the
1462 * date is later). If it is, move it to archi\cversion\filexxx.yyy.
1463 * Otherwise, delete the file.
1465 * If a file is not moved to archi\cversion\ because of an error, all the
1466 * rest of the 'unmoved' driver files are removed from archi\. If one or
1467 * more of the driver's files was already moved to archi\cversion\, it
1468 * potentially leaves the driver in a partially updated state. Version
1469 * trauma will most likely occur if an client attempts to use any printer
1470 * bound to the driver. Perhaps a rewrite to make sure the moves can be
1471 * done is appropriate... later JRR
1474 DEBUG(5,("Moving files now !\n"));
1476 if (driver
->driverpath
&& strlen(driver
->driverpath
)) {
1477 slprintf(new_name
, sizeof(new_name
)-1, "%s/%s", architecture
, driver
->driverpath
);
1478 slprintf(old_name
, sizeof(old_name
)-1, "%s/%s", new_dir
, driver
->driverpath
);
1479 if (ver
!= -1 && (ver
=file_version_is_newer(conn
, new_name
, old_name
)) > 0) {
1481 status
= rename_internals(conn
, new_name
, old_name
, True
);
1482 if (!NT_STATUS_IS_OK(status
)) {
1483 DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
1484 new_name
, old_name
));
1485 *perr
= ntstatus_to_werror(status
);
1486 unlink_internals(conn
, 0, new_name
);
1491 unlink_internals(conn
, 0, new_name
);
1494 if (driver
->datafile
&& strlen(driver
->datafile
)) {
1495 if (!strequal(driver
->datafile
, driver
->driverpath
)) {
1496 slprintf(new_name
, sizeof(new_name
)-1, "%s/%s", architecture
, driver
->datafile
);
1497 slprintf(old_name
, sizeof(old_name
)-1, "%s/%s", new_dir
, driver
->datafile
);
1498 if (ver
!= -1 && (ver
=file_version_is_newer(conn
, new_name
, old_name
)) > 0) {
1500 status
= rename_internals(conn
, new_name
, old_name
, True
);
1501 if (!NT_STATUS_IS_OK(status
)) {
1502 DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
1503 new_name
, old_name
));
1504 *perr
= ntstatus_to_werror(status
);
1505 unlink_internals(conn
, 0, new_name
);
1510 unlink_internals(conn
, 0, new_name
);
1514 if (driver
->configfile
&& strlen(driver
->configfile
)) {
1515 if (!strequal(driver
->configfile
, driver
->driverpath
) &&
1516 !strequal(driver
->configfile
, driver
->datafile
)) {
1517 slprintf(new_name
, sizeof(new_name
)-1, "%s/%s", architecture
, driver
->configfile
);
1518 slprintf(old_name
, sizeof(old_name
)-1, "%s/%s", new_dir
, driver
->configfile
);
1519 if (ver
!= -1 && (ver
=file_version_is_newer(conn
, new_name
, old_name
)) > 0) {
1521 status
= rename_internals(conn
, new_name
, old_name
, True
);
1522 if (!NT_STATUS_IS_OK(status
)) {
1523 DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
1524 new_name
, old_name
));
1525 *perr
= ntstatus_to_werror(status
);
1526 unlink_internals(conn
, 0, new_name
);
1531 unlink_internals(conn
, 0, new_name
);
1535 if (driver
->helpfile
&& strlen(driver
->helpfile
)) {
1536 if (!strequal(driver
->helpfile
, driver
->driverpath
) &&
1537 !strequal(driver
->helpfile
, driver
->datafile
) &&
1538 !strequal(driver
->helpfile
, driver
->configfile
)) {
1539 slprintf(new_name
, sizeof(new_name
)-1, "%s/%s", architecture
, driver
->helpfile
);
1540 slprintf(old_name
, sizeof(old_name
)-1, "%s/%s", new_dir
, driver
->helpfile
);
1541 if (ver
!= -1 && (ver
=file_version_is_newer(conn
, new_name
, old_name
)) > 0) {
1543 status
= rename_internals(conn
, new_name
, old_name
, True
);
1544 if (!NT_STATUS_IS_OK(status
)) {
1545 DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
1546 new_name
, old_name
));
1547 *perr
= ntstatus_to_werror(status
);
1548 unlink_internals(conn
, 0, new_name
);
1553 unlink_internals(conn
, 0, new_name
);
1557 if (driver
->dependentfiles
) {
1558 for (i
=0; *driver
->dependentfiles
[i
]; i
++) {
1559 if (!strequal(driver
->dependentfiles
[i
], driver
->driverpath
) &&
1560 !strequal(driver
->dependentfiles
[i
], driver
->datafile
) &&
1561 !strequal(driver
->dependentfiles
[i
], driver
->configfile
) &&
1562 !strequal(driver
->dependentfiles
[i
], driver
->helpfile
)) {
1564 for (j
=0; j
< i
; j
++) {
1565 if (strequal(driver
->dependentfiles
[i
], driver
->dependentfiles
[j
])) {
1570 slprintf(new_name
, sizeof(new_name
)-1, "%s/%s", architecture
, driver
->dependentfiles
[i
]);
1571 slprintf(old_name
, sizeof(old_name
)-1, "%s/%s", new_dir
, driver
->dependentfiles
[i
]);
1572 if (ver
!= -1 && (ver
=file_version_is_newer(conn
, new_name
, old_name
)) > 0) {
1574 status
= rename_internals(conn
, new_name
, old_name
, True
);
1575 if (!NT_STATUS_IS_OK(status
)) {
1576 DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
1577 new_name
, old_name
));
1578 *perr
= ntstatus_to_werror(status
);
1579 unlink_internals(conn
, 0, new_name
);
1584 unlink_internals(conn
, 0, new_name
);
1590 close_cnum(conn
, user
->vuid
);
1593 return ver
== -1 ? False
: True
;
1596 /****************************************************************************
1597 ****************************************************************************/
1598 static uint32
add_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3
*driver
)
1601 fstring architecture
;
1607 TDB_DATA kbuf
, dbuf
;
1609 get_short_archi(architecture
, driver
->environment
);
1611 /* The names are relative. We store them in the form: \print$\arch\version\driver.xxx
1612 * \\server is added in the rpc server layer.
1613 * It does make sense to NOT store the server's name in the printer TDB.
1616 slprintf(directory
, sizeof(directory
)-1, "\\print$\\%s\\%d\\", architecture
, driver
->cversion
);
1618 /* .inf files do not always list a file for each of the four standard files.
1619 * Don't prepend a path to a null filename, or client claims:
1620 * "The server on which the printer resides does not have a suitable
1621 * <printer driver name> printer driver installed. Click OK if you
1622 * wish to install the driver on your local machine."
1624 if (strlen(driver
->driverpath
)) {
1625 fstrcpy(temp_name
, driver
->driverpath
);
1626 slprintf(driver
->driverpath
, sizeof(driver
->driverpath
)-1, "%s%s", directory
, temp_name
);
1629 if (strlen(driver
->datafile
)) {
1630 fstrcpy(temp_name
, driver
->datafile
);
1631 slprintf(driver
->datafile
, sizeof(driver
->datafile
)-1, "%s%s", directory
, temp_name
);
1634 if (strlen(driver
->configfile
)) {
1635 fstrcpy(temp_name
, driver
->configfile
);
1636 slprintf(driver
->configfile
, sizeof(driver
->configfile
)-1, "%s%s", directory
, temp_name
);
1639 if (strlen(driver
->helpfile
)) {
1640 fstrcpy(temp_name
, driver
->helpfile
);
1641 slprintf(driver
->helpfile
, sizeof(driver
->helpfile
)-1, "%s%s", directory
, temp_name
);
1644 if (driver
->dependentfiles
) {
1645 for (i
=0; *driver
->dependentfiles
[i
]; i
++) {
1646 fstrcpy(temp_name
, driver
->dependentfiles
[i
]);
1647 slprintf(driver
->dependentfiles
[i
], sizeof(driver
->dependentfiles
[i
])-1, "%s%s", directory
, temp_name
);
1651 slprintf(key
, sizeof(key
)-1, "%s%s/%d/%s", DRIVERS_PREFIX
, architecture
, driver
->cversion
, driver
->name
);
1652 dos_to_unix(key
); /* Convert key to unix-codepage */
1654 DEBUG(5,("add_a_printer_driver_3: Adding driver with key %s\n", key
));
1661 len
+= tdb_pack(buf
+len
, buflen
-len
, "dffffffff",
1664 driver
->environment
,
1669 driver
->monitorname
,
1670 driver
->defaultdatatype
);
1672 if (driver
->dependentfiles
) {
1673 for (i
=0; *driver
->dependentfiles
[i
]; i
++) {
1674 len
+= tdb_pack(buf
+len
, buflen
-len
, "f",
1675 driver
->dependentfiles
[i
]);
1679 if (len
!= buflen
) {
1682 tb
= (char *)Realloc(buf
, len
);
1684 DEBUG(0,("add_a_printer_driver_3: failed to enlarge buffer\n!"));
1695 kbuf
.dsize
= strlen(key
)+1;
1699 ret
= tdb_store(tdb_drivers
, kbuf
, dbuf
, TDB_REPLACE
);
1703 DEBUG(0,("add_a_printer_driver_3: Adding driver with key %s failed.\n", key
));
1709 /****************************************************************************
1710 ****************************************************************************/
1711 static uint32
add_a_printer_driver_6(NT_PRINTER_DRIVER_INFO_LEVEL_6
*driver
)
1713 NT_PRINTER_DRIVER_INFO_LEVEL_3 info3
;
1716 info3
.cversion
= driver
->version
;
1717 fstrcpy(info3
.name
,driver
->name
);
1718 fstrcpy(info3
.environment
,driver
->environment
);
1719 fstrcpy(info3
.driverpath
,driver
->driverpath
);
1720 fstrcpy(info3
.datafile
,driver
->datafile
);
1721 fstrcpy(info3
.configfile
,driver
->configfile
);
1722 fstrcpy(info3
.helpfile
,driver
->helpfile
);
1723 fstrcpy(info3
.monitorname
,driver
->monitorname
);
1724 fstrcpy(info3
.defaultdatatype
,driver
->defaultdatatype
);
1725 info3
.dependentfiles
= driver
->dependentfiles
;
1727 return add_a_printer_driver_3(&info3
);
1731 /****************************************************************************
1732 ****************************************************************************/
1733 static WERROR
get_a_printer_driver_3_default(NT_PRINTER_DRIVER_INFO_LEVEL_3
**info_ptr
, const fstring in_prt
, const fstring in_arch
)
1735 NT_PRINTER_DRIVER_INFO_LEVEL_3 info
;
1739 fstrcpy(info
.name
, in_prt
);
1740 fstrcpy(info
.defaultdatatype
, "RAW");
1742 fstrcpy(info
.driverpath
, "");
1743 fstrcpy(info
.datafile
, "");
1744 fstrcpy(info
.configfile
, "");
1745 fstrcpy(info
.helpfile
, "");
1747 if ((info
.dependentfiles
=(fstring
*)malloc(2*sizeof(fstring
))) == NULL
)
1750 memset(info
.dependentfiles
, '\0', 2*sizeof(fstring
));
1751 fstrcpy(info
.dependentfiles
[0], "");
1753 *info_ptr
= memdup(&info
, sizeof(info
));
1758 /****************************************************************************
1759 ****************************************************************************/
1760 static WERROR
get_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3
**info_ptr
, const fstring in_prt
, const fstring in_arch
, uint32 version
)
1762 NT_PRINTER_DRIVER_INFO_LEVEL_3 driver
;
1763 TDB_DATA kbuf
, dbuf
;
1764 fstring architecture
;
1769 ZERO_STRUCT(driver
);
1771 get_short_archi(architecture
, in_arch
);
1773 DEBUG(8,("get_a_printer_driver_3: [%s%s/%d/%s]\n", DRIVERS_PREFIX
, architecture
, version
, in_prt
));
1775 slprintf(key
, sizeof(key
)-1, "%s%s/%d/%s", DRIVERS_PREFIX
, architecture
, version
, in_prt
);
1778 kbuf
.dsize
= strlen(key
)+1;
1780 dbuf
= tdb_fetch(tdb_drivers
, kbuf
);
1782 return WERR_UNKNOWN_PRINTER_DRIVER
;
1784 len
+= tdb_unpack(dbuf
.dptr
, dbuf
.dsize
, "dffffffff",
1793 driver
.defaultdatatype
);
1796 while (len
< dbuf
.dsize
) {
1799 tddfs
= (fstring
*)Realloc(driver
.dependentfiles
,
1800 sizeof(fstring
)*(i
+2));
1801 if (tddfs
== NULL
) {
1802 DEBUG(0,("get_a_printer_driver_3: failed to enlarge buffer!\n"));
1805 else driver
.dependentfiles
= tddfs
;
1807 len
+= tdb_unpack(dbuf
.dptr
+len
, dbuf
.dsize
-len
, "f",
1808 &driver
.dependentfiles
[i
]);
1811 if (driver
.dependentfiles
!= NULL
)
1812 fstrcpy(driver
.dependentfiles
[i
], "");
1814 SAFE_FREE(dbuf
.dptr
);
1816 if (len
!= dbuf
.dsize
) {
1817 SAFE_FREE(driver
.dependentfiles
);
1819 return get_a_printer_driver_3_default(info_ptr
, in_prt
, in_arch
);
1822 *info_ptr
= (NT_PRINTER_DRIVER_INFO_LEVEL_3
*)memdup(&driver
, sizeof(driver
));
1827 /****************************************************************************
1828 ****************************************************************************/
1829 uint32
get_a_printer_driver_9x_compatible(pstring line
, const fstring model
)
1831 NT_PRINTER_DRIVER_INFO_LEVEL_3
*info3
;
1837 slprintf(key
, sizeof(key
)-1, "%s%s/%d/%s", DRIVERS_PREFIX
, "WIN40", 0, model
);
1838 DEBUG(10,("driver key: [%s]\n", key
));
1841 kbuf
.dsize
= strlen(key
)+1;
1842 if (!tdb_exists(tdb_drivers
, kbuf
))
1846 get_a_printer_driver_3(&info3
, model
, "Windows 4.0", 0);
1848 DEBUGADD(10,("info3->name [%s]\n", info3
->name
));
1849 DEBUGADD(10,("info3->datafile [%s]\n", info3
->datafile
));
1850 DEBUGADD(10,("info3->helpfile [%s]\n", info3
->helpfile
));
1851 DEBUGADD(10,("info3->monitorname [%s]\n", info3
->monitorname
));
1852 DEBUGADD(10,("info3->defaultdatatype [%s]\n", info3
->defaultdatatype
));
1853 for (i
=0; info3
->dependentfiles
&& *info3
->dependentfiles
[i
]; i
++) {
1854 DEBUGADD(10,("info3->dependentfiles [%s]\n", info3
->dependentfiles
[i
]));
1856 DEBUGADD(10,("info3->environment [%s]\n", info3
->environment
));
1857 DEBUGADD(10,("info3->driverpath [%s]\n", info3
->driverpath
));
1858 DEBUGADD(10,("info3->configfile [%s]\n", info3
->configfile
));
1860 /*pstrcat(line, info3->name); pstrcat(line, ":");*/
1861 trim_string(info3
->driverpath
, "\\print$\\WIN40\\0\\", 0);
1862 pstrcat(line
, info3
->driverpath
);
1864 trim_string(info3
->datafile
, "\\print$\\WIN40\\0\\", 0);
1865 pstrcat(line
, info3
->datafile
);
1867 trim_string(info3
->helpfile
, "\\print$\\WIN40\\0\\", 0);
1868 pstrcat(line
, info3
->helpfile
);
1870 trim_string(info3
->monitorname
, "\\print$\\WIN40\\0\\", 0);
1871 pstrcat(line
, info3
->monitorname
);
1873 pstrcat(line
, "RAW"); /*info3->defaultdatatype);*/
1876 for (i
=0; info3
->dependentfiles
&& *info3
->dependentfiles
[i
]; i
++) {
1878 pstrcat(line
, ","); /* don't end in a "," */
1879 trim_string(info3
->dependentfiles
[i
], "\\print$\\WIN40\\0\\", 0);
1880 pstrcat(line
, info3
->dependentfiles
[i
]);
1888 /****************************************************************************
1889 Debugging function, dump at level 6 the struct in the logs.
1890 ****************************************************************************/
1892 static uint32
dump_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver
, uint32 level
)
1895 NT_PRINTER_DRIVER_INFO_LEVEL_3
*info3
;
1898 DEBUG(106,("Dumping printer driver at level [%d]\n", level
));
1904 if (driver
.info_3
== NULL
)
1907 info3
=driver
.info_3
;
1909 DEBUGADD(106,("version:[%d]\n", info3
->cversion
));
1910 DEBUGADD(106,("name:[%s]\n", info3
->name
));
1911 DEBUGADD(106,("environment:[%s]\n", info3
->environment
));
1912 DEBUGADD(106,("driverpath:[%s]\n", info3
->driverpath
));
1913 DEBUGADD(106,("datafile:[%s]\n", info3
->datafile
));
1914 DEBUGADD(106,("configfile:[%s]\n", info3
->configfile
));
1915 DEBUGADD(106,("helpfile:[%s]\n", info3
->helpfile
));
1916 DEBUGADD(106,("monitorname:[%s]\n", info3
->monitorname
));
1917 DEBUGADD(106,("defaultdatatype:[%s]\n", info3
->defaultdatatype
));
1919 for (i
=0; info3
->dependentfiles
&&
1920 *info3
->dependentfiles
[i
]; i
++) {
1921 DEBUGADD(106,("dependentfile:[%s]\n",
1922 info3
->dependentfiles
[i
]));
1929 DEBUGADD(106,("dump_a_printer_driver: Level %u not implemented\n", (unsigned int)level
));
1937 /****************************************************************************
1938 ****************************************************************************/
1939 static int pack_devicemode(NT_DEVICEMODE
*nt_devmode
, char *buf
, int buflen
)
1943 len
+= tdb_pack(buf
+len
, buflen
-len
, "p", nt_devmode
);
1945 if (!nt_devmode
) return len
;
1947 len
+= tdb_pack(buf
+len
, buflen
-len
, "ffwwwwwwwwwwwwwwwwwwddddddddddddddp",
1948 nt_devmode
->devicename
,
1949 nt_devmode
->formname
,
1951 nt_devmode
->specversion
,
1952 nt_devmode
->driverversion
,
1954 nt_devmode
->driverextra
,
1955 nt_devmode
->orientation
,
1956 nt_devmode
->papersize
,
1957 nt_devmode
->paperlength
,
1958 nt_devmode
->paperwidth
,
1961 nt_devmode
->defaultsource
,
1962 nt_devmode
->printquality
,
1965 nt_devmode
->yresolution
,
1966 nt_devmode
->ttoption
,
1967 nt_devmode
->collate
,
1968 nt_devmode
->logpixels
,
1971 nt_devmode
->bitsperpel
,
1972 nt_devmode
->pelswidth
,
1973 nt_devmode
->pelsheight
,
1974 nt_devmode
->displayflags
,
1975 nt_devmode
->displayfrequency
,
1976 nt_devmode
->icmmethod
,
1977 nt_devmode
->icmintent
,
1978 nt_devmode
->mediatype
,
1979 nt_devmode
->dithertype
,
1980 nt_devmode
->reserved1
,
1981 nt_devmode
->reserved2
,
1982 nt_devmode
->panningwidth
,
1983 nt_devmode
->panningheight
,
1984 nt_devmode
->private);
1987 if (nt_devmode
->private) {
1988 len
+= tdb_pack(buf
+len
, buflen
-len
, "B",
1989 nt_devmode
->driverextra
,
1990 nt_devmode
->private);
1993 DEBUG(8,("Packed devicemode [%s]\n", nt_devmode
->formname
));
1998 /****************************************************************************
1999 ****************************************************************************/
2000 static int pack_specifics(NT_PRINTER_PARAM
*param
, char *buf
, int buflen
)
2004 while (param
!= NULL
) {
2005 len
+= tdb_pack(buf
+len
, buflen
-len
, "pfdB",
2014 len
+= tdb_pack(buf
+len
, buflen
-len
, "p", param
);
2020 /****************************************************************************
2021 Delete a printer - this just deletes the printer info file, any open
2022 handles are not affected.
2023 ****************************************************************************/
2025 uint32
del_a_printer(char *sharename
)
2030 slprintf(key
, sizeof(key
)-1, "%s%s", PRINTERS_PREFIX
, sharename
);
2031 dos_to_unix(key
); /* Convert key to unix-codepage */
2034 kbuf
.dsize
=strlen(key
)+1;
2036 tdb_delete(tdb_printers
, kbuf
);
2040 /* FIXME!!! Reorder so this forward declaration is not necessary --jerry */
2041 static WERROR
get_a_printer_2(NT_PRINTER_INFO_LEVEL_2
**, fstring
);
2042 static void free_nt_printer_info_level_2(NT_PRINTER_INFO_LEVEL_2
**);
2043 /****************************************************************************
2044 ****************************************************************************/
2045 static WERROR
update_a_printer_2(NT_PRINTER_INFO_LEVEL_2
*info
)
2051 TDB_DATA kbuf
, dbuf
;
2054 * in addprinter: no servername and the printer is the name
2055 * in setprinter: servername is \\server
2056 * and printer is \\server\\printer
2058 * Samba manages only local printers.
2059 * we currently don't support things like path=\\other_server\printer
2062 if (info
->servername
[0]!='\0') {
2063 trim_string(info
->printername
, info
->servername
, NULL
);
2064 trim_string(info
->printername
, "\\", NULL
);
2065 info
->servername
[0]='\0';
2069 * JFM: one day I'll forget.
2070 * below that's info->portname because that's the SAMBA sharename
2071 * and I made NT 'thinks' it's the portname
2072 * the info->sharename is the thing you can name when you add a printer
2073 * that's the short-name when you create shared printer for 95/98
2074 * So I've made a limitation in SAMBA: you can only have 1 printer model
2075 * behind a SAMBA share.
2083 len
+= tdb_pack(buf
+len
, buflen
-len
, "dddddddddddfffffPfffff",
2086 info
->default_priority
,
2103 info
->printprocessor
,
2107 len
+= pack_devicemode(info
->devmode
, buf
+len
, buflen
-len
);
2109 len
+= pack_specifics(info
->specific
, buf
+len
, buflen
-len
);
2111 if (buflen
!= len
) {
2114 tb
= (char *)Realloc(buf
, len
);
2116 DEBUG(0,("update_a_printer_2: failed to enlarge buffer!\n"));
2126 slprintf(key
, sizeof(key
)-1, "%s%s", PRINTERS_PREFIX
, info
->sharename
);
2127 dos_to_unix(key
); /* Convert key to unix-codepage */
2130 kbuf
.dsize
= strlen(key
)+1;
2134 ret
= (tdb_store(tdb_printers
, kbuf
, dbuf
, TDB_REPLACE
) == 0? WERR_OK
: WERR_NOMEM
);
2137 if (!W_ERROR_IS_OK(ret
))
2138 DEBUG(8, ("error updating printer to tdb on disk\n"));
2142 DEBUG(8,("packed printer [%s] with driver [%s] portname=[%s] len=%d\n",
2143 info
->sharename
, info
->drivername
, info
->portname
, len
));
2149 /****************************************************************************
2150 ****************************************************************************/
2151 void add_a_specific_param(NT_PRINTER_INFO_LEVEL_2
*info_2
, NT_PRINTER_PARAM
**param
)
2153 NT_PRINTER_PARAM
*current
;
2155 DEBUG(108,("add_a_specific_param\n"));
2157 (*param
)->next
=NULL
;
2159 if (info_2
->specific
== NULL
)
2161 info_2
->specific
=*param
;
2165 current
=info_2
->specific
;
2166 while (current
->next
!= NULL
) {
2167 current
=current
->next
;
2169 current
->next
=*param
;
2175 /****************************************************************************
2176 ****************************************************************************/
2177 BOOL
unlink_specific_param_if_exist(NT_PRINTER_INFO_LEVEL_2
*info_2
, NT_PRINTER_PARAM
*param
)
2179 NT_PRINTER_PARAM
*current
;
2180 NT_PRINTER_PARAM
*previous
;
2182 current
=info_2
->specific
;
2185 if (current
==NULL
) return (False
);
2187 if ( !strcmp(current
->value
, param
->value
) &&
2188 (strlen(current
->value
)==strlen(param
->value
)) ) {
2189 DEBUG(109,("deleting first value\n"));
2190 info_2
->specific
=current
->next
;
2191 SAFE_FREE(current
->data
);
2193 DEBUG(109,("deleted first value\n"));
2197 current
=previous
->next
;
2199 while ( current
!=NULL
) {
2200 if (!strcmp(current
->value
, param
->value
) &&
2201 strlen(current
->value
)==strlen(param
->value
) ) {
2202 DEBUG(109,("deleting current value\n"));
2203 previous
->next
=current
->next
;
2204 SAFE_FREE(current
->data
);
2206 DEBUG(109,("deleted current value\n"));
2210 previous
=previous
->next
;
2211 current
=current
->next
;
2216 /****************************************************************************
2217 Clean up and deallocate a (maybe partially) allocated NT_PRINTER_PARAM.
2218 ****************************************************************************/
2219 void free_nt_printer_param(NT_PRINTER_PARAM
**param_ptr
)
2221 NT_PRINTER_PARAM
*param
= *param_ptr
;
2226 DEBUG(106,("free_nt_printer_param: deleting param [%s]\n", param
->value
));
2228 SAFE_FREE(param
->data
);
2229 SAFE_FREE(*param_ptr
);
2232 /****************************************************************************
2233 Malloc and return an NT devicemode.
2234 ****************************************************************************/
2236 NT_DEVICEMODE
*construct_nt_devicemode(const fstring default_devicename
)
2239 char adevice
[MAXDEVICENAME
+1];
2240 NT_DEVICEMODE
*nt_devmode
= (NT_DEVICEMODE
*)malloc(sizeof(NT_DEVICEMODE
));
2242 if (nt_devmode
== NULL
) {
2243 DEBUG(0,("construct_nt_devicemode: malloc fail.\n"));
2247 ZERO_STRUCTP(nt_devmode
);
2249 safe_strcpy(adevice
, default_devicename
, sizeof(adevice
)-1);
2250 fstrcpy(nt_devmode
->devicename
, adevice
);
2252 fstrcpy(nt_devmode
->formname
, "Letter");
2254 nt_devmode
->specversion
= 0x0401;
2255 nt_devmode
->driverversion
= 0x0400;
2256 nt_devmode
->size
= 0x00DC;
2257 nt_devmode
->driverextra
= 0x0000;
2258 nt_devmode
->fields
= FORMNAME
| TTOPTION
| PRINTQUALITY
|
2259 DEFAULTSOURCE
| COPIES
| SCALE
|
2260 PAPERSIZE
| ORIENTATION
;
2261 nt_devmode
->orientation
= 1;
2262 nt_devmode
->papersize
= PAPER_LETTER
;
2263 nt_devmode
->paperlength
= 0;
2264 nt_devmode
->paperwidth
= 0;
2265 nt_devmode
->scale
= 0x64;
2266 nt_devmode
->copies
= 1;
2267 nt_devmode
->defaultsource
= BIN_FORMSOURCE
;
2268 nt_devmode
->printquality
= RES_HIGH
; /* 0x0258 */
2269 nt_devmode
->color
= COLOR_MONOCHROME
;
2270 nt_devmode
->duplex
= DUP_SIMPLEX
;
2271 nt_devmode
->yresolution
= 0;
2272 nt_devmode
->ttoption
= TT_SUBDEV
;
2273 nt_devmode
->collate
= COLLATE_FALSE
;
2274 nt_devmode
->icmmethod
= 0;
2275 nt_devmode
->icmintent
= 0;
2276 nt_devmode
->mediatype
= 0;
2277 nt_devmode
->dithertype
= 0;
2279 /* non utilisés par un driver d'imprimante */
2280 nt_devmode
->logpixels
= 0;
2281 nt_devmode
->bitsperpel
= 0;
2282 nt_devmode
->pelswidth
= 0;
2283 nt_devmode
->pelsheight
= 0;
2284 nt_devmode
->displayflags
= 0;
2285 nt_devmode
->displayfrequency
= 0;
2286 nt_devmode
->reserved1
= 0;
2287 nt_devmode
->reserved2
= 0;
2288 nt_devmode
->panningwidth
= 0;
2289 nt_devmode
->panningheight
= 0;
2291 nt_devmode
->private = NULL
;
2295 /****************************************************************************
2296 Deepcopy an NT devicemode.
2297 ****************************************************************************/
2299 NT_DEVICEMODE
*dup_nt_devicemode(NT_DEVICEMODE
*nt_devicemode
)
2301 NT_DEVICEMODE
*new_nt_devicemode
= NULL
;
2303 if ((new_nt_devicemode
= (NT_DEVICEMODE
*)memdup(nt_devicemode
, sizeof(NT_DEVICEMODE
))) == NULL
) {
2304 DEBUG(0,("dup_nt_devicemode: malloc fail.\n"));
2308 new_nt_devicemode
->private = NULL
;
2309 if (nt_devicemode
->private != NULL
) {
2310 if ((new_nt_devicemode
->private = memdup(nt_devicemode
->private, nt_devicemode
->driverextra
)) == NULL
) {
2311 SAFE_FREE(new_nt_devicemode
);
2312 DEBUG(0,("dup_nt_devicemode: malloc fail.\n"));
2317 return new_nt_devicemode
;
2320 /****************************************************************************
2321 Clean up and deallocate a (maybe partially) allocated NT_DEVICEMODE.
2322 ****************************************************************************/
2324 void free_nt_devicemode(NT_DEVICEMODE
**devmode_ptr
)
2326 NT_DEVICEMODE
*nt_devmode
= *devmode_ptr
;
2328 if(nt_devmode
== NULL
)
2331 DEBUG(106,("free_nt_devicemode: deleting DEVMODE\n"));
2333 SAFE_FREE(nt_devmode
->private);
2334 SAFE_FREE(*devmode_ptr
);
2337 /****************************************************************************
2338 Clean up and deallocate a (maybe partially) allocated NT_PRINTER_INFO_LEVEL_2.
2339 ****************************************************************************/
2340 static void free_nt_printer_info_level_2(NT_PRINTER_INFO_LEVEL_2
**info_ptr
)
2342 NT_PRINTER_INFO_LEVEL_2
*info
= *info_ptr
;
2343 NT_PRINTER_PARAM
*param_ptr
;
2348 DEBUG(106,("free_nt_printer_info_level_2: deleting info\n"));
2350 free_nt_devicemode(&info
->devmode
);
2352 for(param_ptr
= info
->specific
; param_ptr
; ) {
2353 NT_PRINTER_PARAM
*tofree
= param_ptr
;
2355 param_ptr
= param_ptr
->next
;
2356 free_nt_printer_param(&tofree
);
2359 SAFE_FREE(*info_ptr
);
2363 /****************************************************************************
2364 ****************************************************************************/
2365 static int unpack_devicemode(NT_DEVICEMODE
**nt_devmode
, char *buf
, int buflen
)
2369 NT_DEVICEMODE devmode
;
2371 ZERO_STRUCT(devmode
);
2373 len
+= tdb_unpack(buf
+len
, buflen
-len
, "p", nt_devmode
);
2375 if (!*nt_devmode
) return len
;
2377 len
+= tdb_unpack(buf
+len
, buflen
-len
, "ffwwwwwwwwwwwwwwwwwwddddddddddddddp",
2381 &devmode
.specversion
,
2382 &devmode
.driverversion
,
2384 &devmode
.driverextra
,
2385 &devmode
.orientation
,
2387 &devmode
.paperlength
,
2388 &devmode
.paperwidth
,
2391 &devmode
.defaultsource
,
2392 &devmode
.printquality
,
2395 &devmode
.yresolution
,
2401 &devmode
.bitsperpel
,
2403 &devmode
.pelsheight
,
2404 &devmode
.displayflags
,
2405 &devmode
.displayfrequency
,
2409 &devmode
.dithertype
,
2412 &devmode
.panningwidth
,
2413 &devmode
.panningheight
,
2416 if (devmode
.private) {
2417 /* the len in tdb_unpack is an int value and
2418 * devmode.driverextra is only a short
2420 len
+= tdb_unpack(buf
+len
, buflen
-len
, "B", &extra_len
, &devmode
.private);
2421 devmode
.driverextra
=(uint16
)extra_len
;
2423 /* check to catch an invalid TDB entry so we don't segfault */
2424 if (devmode
.driverextra
== 0) {
2425 devmode
.private = NULL
;
2429 *nt_devmode
= (NT_DEVICEMODE
*)memdup(&devmode
, sizeof(devmode
));
2431 DEBUG(8,("Unpacked devicemode [%s](%s)\n", devmode
.devicename
, devmode
.formname
));
2432 if (devmode
.private)
2433 DEBUG(8,("with a private section of %d bytes\n", devmode
.driverextra
));
2438 /****************************************************************************
2439 ****************************************************************************/
2440 static int unpack_specifics(NT_PRINTER_PARAM
**list
, char *buf
, int buflen
)
2443 NT_PRINTER_PARAM param
, *p
;
2448 len
+= tdb_unpack(buf
+len
, buflen
-len
, "p", &p
);
2451 len
+= tdb_unpack(buf
+len
, buflen
-len
, "fdB",
2457 *list
= memdup(¶m
, sizeof(param
));
2459 DEBUG(8,("specific: [%s], len: %d\n", param
.value
, param
.data_len
));
2465 static void map_to_os2_driver(fstring drivername
)
2467 static BOOL initialised
=False
;
2468 static fstring last_from
,last_to
;
2469 char *mapfile
= lp_os2_driver_map();
2470 char **lines
= NULL
;
2474 if (!strlen(drivername
))
2481 *last_from
= *last_to
= 0;
2485 if (strequal(drivername
,last_from
)) {
2486 DEBUG(3,("Mapped Windows driver %s to OS/2 driver %s\n",drivername
,last_to
));
2487 fstrcpy(drivername
,last_to
);
2491 lines
= file_lines_load(mapfile
, &numlines
, True
);
2492 if (numlines
== 0) {
2493 DEBUG(0,("No entries in OS/2 driver map %s\n",mapfile
));
2497 DEBUG(4,("Scanning OS/2 driver map %s\n",mapfile
));
2499 for( i
= 0; i
< numlines
; i
++) {
2500 char *nt_name
= lines
[i
];
2501 char *os2_name
= strchr(nt_name
,'=');
2508 while (isspace(*nt_name
))
2511 if (!*nt_name
|| strchr("#;",*nt_name
))
2515 int l
= strlen(nt_name
);
2516 while (l
&& isspace(nt_name
[l
-1])) {
2522 while (isspace(*os2_name
))
2526 int l
= strlen(os2_name
);
2527 while (l
&& isspace(os2_name
[l
-1])) {
2533 if (strequal(nt_name
,drivername
)) {
2534 DEBUG(3,("Mapped windows driver %s to os2 driver%s\n",drivername
,os2_name
));
2535 fstrcpy(last_from
,drivername
);
2536 fstrcpy(last_to
,os2_name
);
2537 fstrcpy(drivername
,os2_name
);
2538 file_lines_free(lines
);
2543 file_lines_free(lines
);
2546 /****************************************************************************
2547 get a default printer info 2 struct
2548 ****************************************************************************/
2549 static WERROR
get_a_printer_2_default(NT_PRINTER_INFO_LEVEL_2
**info_ptr
, fstring sharename
)
2552 NT_PRINTER_INFO_LEVEL_2 info
;
2556 snum
= lp_servicenumber(sharename
);
2558 slprintf(info
.servername
, sizeof(info
.servername
)-1, "\\\\%s", get_called_name());
2559 slprintf(info
.printername
, sizeof(info
.printername
)-1, "\\\\%s\\%s",
2560 get_called_name(), sharename
);
2561 fstrcpy(info
.sharename
, sharename
);
2562 fstrcpy(info
.portname
, SAMBA_PRINTER_PORT_NAME
);
2563 fstrcpy(info
.drivername
, lp_printerdriver(snum
));
2565 /* by setting the driver name to an empty string, a local NT admin
2566 can now run the **local** APW to install a local printer driver
2567 for a Samba shared printer in 2.2. Without this, drivers **must** be
2568 installed on the Samba server for NT clients --jerry */
2569 #if 0 /* JERRY --do not uncomment-- */
2570 if (!*info
.drivername
)
2571 fstrcpy(info
.drivername
, "NO DRIVER AVAILABLE FOR THIS PRINTER");
2575 DEBUG(10,("get_a_printer_2_default: driver name set to [%s]\n", info
.drivername
));
2577 pstrcpy(info
.comment
, "");
2578 fstrcpy(info
.printprocessor
, "winprint");
2579 fstrcpy(info
.datatype
, "RAW");
2581 info
.attributes
= PRINTER_ATTRIBUTE_SHARED
| PRINTER_ATTRIBUTE_NETWORK
; /* attributes */
2583 info
.starttime
= 0; /* Minutes since 12:00am GMT */
2584 info
.untiltime
= 0; /* Minutes since 12:00am GMT */
2586 info
.default_priority
= 1;
2587 info
.setuptime
= (uint32
)time(NULL
);
2590 * I changed this as I think it is better to have a generic
2591 * DEVMODE than to crash Win2k explorer.exe --jerry
2592 * See the HP Deskjet 990c Win2k drivers for an example.
2594 * However the default devmode appears to cause problems
2595 * with the HP CLJ 8500 PCL driver. Hence the addition of
2596 * the "default devmode" parameter --jerry 22/01/2002
2599 if (lp_default_devmode(snum
)) {
2600 if ((info
.devmode
= construct_nt_devicemode(info
.printername
)) == NULL
)
2604 info
.devmode
= NULL
;
2607 /* This will get the current RPC talloc context, but we should be
2608 passing this as a parameter... fixme... JRA ! */
2610 if (!nt_printing_getsec(get_talloc_ctx(), sharename
, &info
.secdesc_buf
))
2613 *info_ptr
= (NT_PRINTER_INFO_LEVEL_2
*)memdup(&info
, sizeof(info
));
2615 DEBUG(0,("get_a_printer_2_default: malloc fail.\n"));
2623 free_nt_devicemode(&info
.devmode
);
2624 return WERR_ACCESS_DENIED
;
2627 /****************************************************************************
2628 ****************************************************************************/
2629 static WERROR
get_a_printer_2(NT_PRINTER_INFO_LEVEL_2
**info_ptr
, fstring sharename
)
2632 NT_PRINTER_INFO_LEVEL_2 info
;
2634 TDB_DATA kbuf
, dbuf
;
2635 fstring printername
;
2639 slprintf(key
, sizeof(key
)-1, "%s%s", PRINTERS_PREFIX
, sharename
);
2640 dos_to_unix(key
); /* Convert key to unix-codepage */
2643 kbuf
.dsize
= strlen(key
)+1;
2645 dbuf
= tdb_fetch(tdb_printers
, kbuf
);
2647 return get_a_printer_2_default(info_ptr
, sharename
);
2649 len
+= tdb_unpack(dbuf
.dptr
+len
, dbuf
.dsize
-len
, "dddddddddddfffffPfffff",
2652 &info
.default_priority
,
2669 info
.printprocessor
,
2673 /* Samba has to have shared raw drivers. */
2674 info
.attributes
|= (PRINTER_ATTRIBUTE_SHARED
| PRINTER_ATTRIBUTE_NETWORK
);
2676 /* Restore the stripped strings. */
2677 slprintf(info
.servername
, sizeof(info
.servername
)-1, "\\\\%s", get_called_name());
2678 slprintf(printername
, sizeof(printername
)-1, "\\\\%s\\%s", get_called_name(),
2680 fstrcpy(info
.printername
, printername
);
2682 len
+= unpack_devicemode(&info
.devmode
,dbuf
.dptr
+len
, dbuf
.dsize
-len
);
2685 * Some client drivers freak out if there is a NULL devmode
2686 * (probably the driver is not checking before accessing
2687 * the devmode pointer) --jerry
2689 * See comments in get_a_printer_2_default()
2692 if (lp_default_devmode(lp_servicenumber(sharename
)) && !info
.devmode
)
2694 DEBUG(8,("get_a_printer_2: Constructing a default device mode for [%s]\n",
2696 info
.devmode
= construct_nt_devicemode(printername
);
2699 len
+= unpack_specifics(&info
.specific
,dbuf
.dptr
+len
, dbuf
.dsize
-len
);
2701 /* This will get the current RPC talloc context, but we should be
2702 passing this as a parameter... fixme... JRA ! */
2704 nt_printing_getsec(get_talloc_ctx(), sharename
, &info
.secdesc_buf
);
2706 /* Fix for OS/2 drivers. */
2708 if (get_remote_arch() == RA_OS2
)
2709 map_to_os2_driver(info
.drivername
);
2711 SAFE_FREE(dbuf
.dptr
);
2712 *info_ptr
=memdup(&info
, sizeof(info
));
2714 DEBUG(9,("Unpacked printer [%s] name [%s] running driver [%s]\n",
2715 sharename
, info
.printername
, info
.drivername
));
2720 /****************************************************************************
2721 debugging function, dump at level 6 the struct in the logs
2722 ****************************************************************************/
2723 static uint32
dump_a_printer(NT_PRINTER_INFO_LEVEL printer
, uint32 level
)
2726 NT_PRINTER_INFO_LEVEL_2
*info2
;
2728 DEBUG(106,("Dumping printer at level [%d]\n", level
));
2734 if (printer
.info_2
== NULL
)
2738 info2
=printer
.info_2
;
2740 DEBUGADD(106,("attributes:[%d]\n", info2
->attributes
));
2741 DEBUGADD(106,("priority:[%d]\n", info2
->priority
));
2742 DEBUGADD(106,("default_priority:[%d]\n", info2
->default_priority
));
2743 DEBUGADD(106,("starttime:[%d]\n", info2
->starttime
));
2744 DEBUGADD(106,("untiltime:[%d]\n", info2
->untiltime
));
2745 DEBUGADD(106,("status:[%d]\n", info2
->status
));
2746 DEBUGADD(106,("cjobs:[%d]\n", info2
->cjobs
));
2747 DEBUGADD(106,("averageppm:[%d]\n", info2
->averageppm
));
2748 DEBUGADD(106,("changeid:[%d]\n", info2
->changeid
));
2749 DEBUGADD(106,("c_setprinter:[%d]\n", info2
->c_setprinter
));
2750 DEBUGADD(106,("setuptime:[%d]\n", info2
->setuptime
));
2752 DEBUGADD(106,("servername:[%s]\n", info2
->servername
));
2753 DEBUGADD(106,("printername:[%s]\n", info2
->printername
));
2754 DEBUGADD(106,("sharename:[%s]\n", info2
->sharename
));
2755 DEBUGADD(106,("portname:[%s]\n", info2
->portname
));
2756 DEBUGADD(106,("drivername:[%s]\n", info2
->drivername
));
2757 DEBUGADD(106,("comment:[%s]\n", info2
->comment
));
2758 DEBUGADD(106,("location:[%s]\n", info2
->location
));
2759 DEBUGADD(106,("sepfile:[%s]\n", info2
->sepfile
));
2760 DEBUGADD(106,("printprocessor:[%s]\n", info2
->printprocessor
));
2761 DEBUGADD(106,("datatype:[%s]\n", info2
->datatype
));
2762 DEBUGADD(106,("parameters:[%s]\n", info2
->parameters
));
2768 DEBUGADD(106,("dump_a_printer: Level %u not implemented\n", (unsigned int)level
));
2776 /****************************************************************************
2777 Get the parameters we can substitute in an NT print job.
2778 ****************************************************************************/
2780 void get_printer_subst_params(int snum
, fstring
*printername
, fstring
*sharename
, fstring
*portname
)
2782 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
2784 **printername
= **sharename
= **portname
= '\0';
2786 if (!W_ERROR_IS_OK(get_a_printer(&printer
, 2, lp_servicename(snum
))))
2789 fstrcpy(*printername
, printer
->info_2
->printername
);
2790 fstrcpy(*sharename
, printer
->info_2
->sharename
);
2791 fstrcpy(*portname
, printer
->info_2
->portname
);
2793 free_a_printer(&printer
, 2);
2796 /****************************************************************************
2797 Update the changeid time.
2798 This is SO NASTY as some drivers need this to change, others need it
2799 static. This value will change every second, and I must hope that this
2800 is enough..... DON'T CHANGE THIS CODE WITHOUT A TEST MATRIX THE SIZE OF
2802 ****************************************************************************/
2804 static uint32
rev_changeid(void)
2808 get_process_uptime(&tv
);
2811 /* Return changeid as msec since spooler restart */
2812 return tv
.tv_sec
* 1000 + tv
.tv_usec
/ 1000;
2815 * This setting seems to work well but is too untested
2816 * to replace the above calculation. Left in for experiementation
2817 * of the reader --jerry (Tue Mar 12 09:15:05 CST 2002)
2819 return tv
.tv_sec
* 10 + tv
.tv_usec
/ 100000;
2824 * The function below are the high level ones.
2825 * only those ones must be called from the spoolss code.
2829 /****************************************************************************
2830 Modify a printer. This is called from SETPRINTERDATA/DELETEPRINTERDATA.
2831 ****************************************************************************/
2833 WERROR
mod_a_printer(NT_PRINTER_INFO_LEVEL printer
, uint32 level
)
2837 dump_a_printer(printer
, level
);
2844 * Update the changestamp. Emperical tests show that the
2845 * ChangeID is always updated,but c_setprinter is
2846 * global spooler variable (not per printer).
2849 /* ChangeID **must** be increasing over the lifetime
2850 of client's spoolss service in order for the
2851 client's cache to show updates */
2853 printer
.info_2
->changeid
= rev_changeid();
2856 * Because one day someone will ask:
2857 * NT->NT An admin connection to a remote
2858 * printer show changes imeediately in
2859 * the properities dialog
2861 * A non-admin connection will only show the
2862 * changes after viewing the properites page
2863 * 2 times. Seems to be related to a
2864 * race condition in the client between the spooler
2865 * updating the local cache and the Explorer.exe GUI
2866 * actually displaying the properties.
2868 * This is fixed in Win2k. admin/non-admin
2869 * connections both display changes immediately.
2874 result
=update_a_printer_2(printer
.info_2
);
2878 result
=WERR_UNKNOWN_LEVEL
;
2885 /****************************************************************************
2886 Initialize printer devmode & data with previously saved driver init values.
2887 ****************************************************************************/
2889 static BOOL
set_driver_init_2(NT_PRINTER_INFO_LEVEL_2
*info_ptr
)
2893 TDB_DATA kbuf
, dbuf
;
2894 NT_PRINTER_PARAM
*current
;
2895 NT_PRINTER_INFO_LEVEL_2 info
;
2898 * Delete any printer data 'specifics' already set. When called for driver
2899 * replace, there will generally be some, but during an add printer, there
2900 * should not be any (if there are delete them).
2902 while ( (current
=info_ptr
->specific
) != NULL
) {
2903 info_ptr
->specific
=current
->next
;
2904 SAFE_FREE(current
->data
);
2910 slprintf(key
, sizeof(key
)-1, "%s%s", DRIVER_INIT_PREFIX
, info_ptr
->drivername
);
2911 dos_to_unix(key
); /* Convert key to unix-codepage */
2914 kbuf
.dsize
= strlen(key
)+1;
2916 dbuf
= tdb_fetch(tdb_drivers
, kbuf
);
2919 * When changing to a driver that has no init info in the tdb, remove
2920 * the previous drivers init info and leave the new on blank.
2922 free_nt_devicemode(&info_ptr
->devmode
);
2927 * Get the saved DEVMODE..
2929 len
+= unpack_devicemode(&info
.devmode
,dbuf
.dptr
+len
, dbuf
.dsize
-len
);
2932 * The saved DEVMODE contains the devicename from the printer used during
2933 * the initialization save. Change it to reflect the new printer.
2935 ZERO_STRUCT(info
.devmode
->devicename
);
2936 fstrcpy(info
.devmode
->devicename
, info_ptr
->printername
);
2940 * NT/2k does not change out the entire DeviceMode of a printer
2941 * when changing the driver. Only the driverextra, private, &
2942 * driverversion fields. --jerry (Thu Mar 14 08:58:43 CST 2002)
2944 * Later e4xamination revealed that Windows NT/2k does reset the
2945 * the printer's device mode, bit **only** when you change a
2946 * property of the device mode such as the page orientation.
2953 * Bind the saved DEVMODE to the new the printer.
2955 free_nt_devicemode(&info_ptr
->devmode
);
2956 info_ptr
->devmode
= info
.devmode
;
2958 /* copy the entire devmode if we currently don't have one */
2960 if (!info_ptr
->devmode
) {
2961 DEBUG(10,("set_driver_init_2: Current Devmode is NULL. Copying entire Device Mode\n"));
2962 info_ptr
->devmode
= info
.devmode
;
2965 /* only set the necessary fields */
2967 DEBUG(10,("set_driver_init_2: Setting driverversion [0x%x] and private data [0x%x]\n",
2968 info
.devmode
->driverversion
, info
.devmode
->driverextra
));
2970 info_ptr
->devmode
->driverversion
= info
.devmode
->driverversion
;
2972 SAFE_FREE(info_ptr
->devmode
->private);
2973 info_ptr
->devmode
->private = NULL
;
2975 if (info
.devmode
->driverversion
)
2976 info_ptr
->devmode
->private = memdup(info
.devmode
->private, info
.devmode
->driverversion
);
2978 free_nt_devicemode(&info
.devmode
);
2982 DEBUG(10,("set_driver_init_2: Set printer [%s] init DEVMODE for driver [%s]\n",
2983 info_ptr
->printername
, info_ptr
->drivername
));
2986 * Add the printer data 'specifics' to the new printer
2988 len
+= unpack_specifics(&info_ptr
->specific
,dbuf
.dptr
+len
, dbuf
.dsize
-len
);
2990 SAFE_FREE(dbuf
.dptr
);
2995 /****************************************************************************
2996 Initialize printer devmode & data with previously saved driver init values.
2997 When a printer is created using AddPrinter, the drivername bound to the
2998 printer is used to lookup previously saved driver initialization info, which
2999 is bound to the new printer.
3000 ****************************************************************************/
3002 BOOL
set_driver_init(NT_PRINTER_INFO_LEVEL
*printer
, uint32 level
)
3004 BOOL result
= False
;
3009 result
= set_driver_init_2(printer
->info_2
);
3013 DEBUG(0,("set_driver_init: Programmer's error! Unknown driver_init level [%d]\n",
3021 /****************************************************************************
3022 Delete driver init data stored for a specified driver
3023 ****************************************************************************/
3025 BOOL
del_driver_init(char *drivername
)
3030 if (!drivername
|| !*drivername
) {
3031 DEBUG(3,("del_driver_init: No drivername specified!\n"));
3035 slprintf(key
, sizeof(key
)-1, "%s%s", DRIVER_INIT_PREFIX
, drivername
);
3036 dos_to_unix(key
); /* Convert key to unix-codepage */
3039 kbuf
.dsize
= strlen(key
)+1;
3041 DEBUG(6,("del_driver_init: Removing driver init data for [%s]\n", drivername
));
3043 return (tdb_delete(tdb_drivers
, kbuf
) == 0);
3046 /****************************************************************************
3047 Pack up the DEVMODE and specifics for a printer into a 'driver init' entry
3048 in the tdb. Note: this is different from the driver entry and the printer
3049 entry. There should be a single driver init entry for each driver regardless
3050 of whether it was installed from NT or 2K. Technically, they should be
3051 different, but they work out to the same struct.
3052 ****************************************************************************/
3054 static uint32
update_driver_init_2(NT_PRINTER_INFO_LEVEL_2
*info
)
3058 int buflen
, len
, ret
;
3059 TDB_DATA kbuf
, dbuf
;
3066 len
+= pack_devicemode(info
->devmode
, buf
+len
, buflen
-len
);
3068 len
+= pack_specifics(info
->specific
, buf
+len
, buflen
-len
);
3070 if (buflen
!= len
) {
3073 tb
= (char *)Realloc(buf
, len
);
3075 DEBUG(0, ("update_driver_init_2: failed to enlarge buffer!\n"));
3084 slprintf(key
, sizeof(key
)-1, "%s%s", DRIVER_INIT_PREFIX
, info
->drivername
);
3085 dos_to_unix(key
); /* Convert key to unix-codepage */
3088 kbuf
.dsize
= strlen(key
)+1;
3092 ret
= tdb_store(tdb_drivers
, kbuf
, dbuf
, TDB_REPLACE
);
3096 DEBUG(8, ("update_driver_init_2: error updating printer init to tdb on disk\n"));
3100 DEBUG(10,("update_driver_init_2: Saved printer [%s] init DEVMODE & specifics for driver [%s]\n",
3101 info
->sharename
, info
->drivername
));
3106 /****************************************************************************
3107 Update (i.e. save) the driver init info (DEVMODE and specifics) for a printer
3108 ****************************************************************************/
3110 uint32
update_driver_init(NT_PRINTER_INFO_LEVEL printer
, uint32 level
)
3114 dump_a_printer(printer
, level
);
3120 result
=update_driver_init_2(printer
.info_2
);
3131 /****************************************************************************
3132 Convert the printer data value, a REG_BINARY array, into an initialization
3133 DEVMODE. Note: the array must be parsed as if it was a DEVMODE in an rpc...
3134 got to keep the endians happy :).
3135 ****************************************************************************/
3137 static BOOL
convert_driver_init(NT_PRINTER_PARAM
*param
, TALLOC_CTX
*ctx
, NT_DEVICEMODE
*nt_devmode
)
3139 BOOL result
= False
;
3143 ZERO_STRUCT(devmode
);
3145 prs_init(&ps
, 0, ctx
, UNMARSHALL
);
3146 ps
.data_p
= (char *)param
->data
;
3147 ps
.buffer_size
= param
->data_len
;
3149 if (spoolss_io_devmode("phantom DEVMODE", &ps
, 0, &devmode
))
3150 result
= convert_devicemode("", &devmode
, &nt_devmode
);
3152 DEBUG(10,("convert_driver_init: error parsing DEVMODE\n"));
3157 /****************************************************************************
3158 Set the DRIVER_INIT info in the tdb. Requires Win32 client code that:
3160 1. Use the driver's config DLL to this UNC printername and:
3161 a. Call DrvPrintEvent with PRINTER_EVENT_INITIALIZE
3162 b. Call DrvConvertDevMode with CDM_DRIVER_DEFAULT to get default DEVMODE
3163 2. Call SetPrinterData with the 'magic' key and the DEVMODE as data.
3165 The last step triggers saving the "driver initialization" information for
3166 this printer into the tdb. Later, new printers that use this driver will
3167 have this initialization information bound to them. This simulates the
3168 driver initialization, as if it had run on the Samba server (as it would
3171 The Win32 client side code requirement sucks! But until we can run arbitrary
3172 Win32 printer driver code on any Unix that Samba runs on, we are stuck with it.
3174 It would have been easier to use SetPrinter because all the UNMARSHALLING of
3175 the DEVMODE is done there, but 2K/XP clients do not set the DEVMODE... think
3176 about it and you will realize why. JRR 010720
3177 ****************************************************************************/
3179 static WERROR
save_driver_init_2(NT_PRINTER_INFO_LEVEL
*printer
, NT_PRINTER_PARAM
*param
)
3181 WERROR status
= WERR_OK
;
3182 TALLOC_CTX
*ctx
= NULL
;
3183 NT_DEVICEMODE
*nt_devmode
= NULL
;
3184 NT_DEVICEMODE
*tmp_devmode
= printer
->info_2
->devmode
;
3187 * When the DEVMODE is already set on the printer, don't try to unpack it.
3190 if (!printer
->info_2
->devmode
&& param
->data_len
) {
3192 * Set devmode on printer info, so entire printer initialization can be
3196 if ((ctx
= talloc_init()) == NULL
)
3199 if ((nt_devmode
= (NT_DEVICEMODE
*)malloc(sizeof(NT_DEVICEMODE
))) == NULL
) {
3200 status
= WERR_NOMEM
;
3204 ZERO_STRUCTP(nt_devmode
);
3207 * The DEVMODE is held in the 'data' component of the param in raw binary.
3208 * Convert it to to a devmode structure
3210 if (!convert_driver_init(param
, ctx
, nt_devmode
)) {
3211 DEBUG(10,("save_driver_init_2: error converting DEVMODE\n"));
3212 status
= WERR_INVALID_PARAM
;
3216 printer
->info_2
->devmode
= nt_devmode
;
3220 * Pack up and add (or update) the DEVMODE and any current printer data to
3221 * a 'driver init' element in the tdb
3225 if (update_driver_init(*printer
, 2)!=0) {
3226 DEBUG(10,("save_driver_init_2: error updating DEVMODE\n"));
3227 status
= WERR_NOMEM
;
3232 * If driver initialization info was successfully saved, set the current
3233 * printer to match it. This allows initialization of the current printer
3234 * as well as the driver.
3236 status
= mod_a_printer(*printer
, 2);
3237 if (!W_ERROR_IS_OK(status
)) {
3238 DEBUG(10,("save_driver_init_2: error setting DEVMODE on printer [%s]\n",
3239 printer
->info_2
->printername
));
3243 srv_spoolss_sendnotify(p
, handle
);
3247 talloc_destroy(ctx
);
3249 SAFE_FREE(nt_devmode
->private);
3250 SAFE_FREE(nt_devmode
);
3251 printer
->info_2
->devmode
= tmp_devmode
;
3256 /****************************************************************************
3257 Update the driver init info (DEVMODE and specifics) for a printer
3258 ****************************************************************************/
3260 WERROR
save_driver_init(NT_PRINTER_INFO_LEVEL
*printer
, uint32 level
, NT_PRINTER_PARAM
*param
)
3262 WERROR status
= WERR_OK
;
3268 status
=save_driver_init_2(printer
, param
);
3272 status
=WERR_UNKNOWN_LEVEL
;
3279 /****************************************************************************
3280 Get a NT_PRINTER_INFO_LEVEL struct. It returns malloced memory.
3281 ****************************************************************************/
3283 WERROR
get_a_printer(NT_PRINTER_INFO_LEVEL
**pp_printer
, uint32 level
, fstring sharename
)
3286 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
3290 DEBUG(10,("get_a_printer: [%s] level %u\n", sharename
, (unsigned int)level
));
3296 if ((printer
= (NT_PRINTER_INFO_LEVEL
*)malloc(sizeof(NT_PRINTER_INFO_LEVEL
))) == NULL
) {
3297 DEBUG(0,("get_a_printer: malloc fail.\n"));
3300 ZERO_STRUCTP(printer
);
3301 result
=get_a_printer_2(&printer
->info_2
, sharename
);
3302 if (W_ERROR_IS_OK(result
)) {
3303 dump_a_printer(*printer
, level
);
3304 *pp_printer
= printer
;
3311 result
=WERR_UNKNOWN_LEVEL
;
3315 DEBUG(10,("get_a_printer: [%s] level %u returning %s\n", sharename
, (unsigned int)level
, dos_errstr(result
)));
3320 /****************************************************************************
3321 Deletes a NT_PRINTER_INFO_LEVEL struct.
3322 ****************************************************************************/
3324 uint32
free_a_printer(NT_PRINTER_INFO_LEVEL
**pp_printer
, uint32 level
)
3327 NT_PRINTER_INFO_LEVEL
*printer
= *pp_printer
;
3329 DEBUG(104,("freeing a printer at level [%d]\n", level
));
3331 if (printer
== NULL
)
3338 if (printer
->info_2
!= NULL
)
3340 free_nt_printer_info_level_2(&printer
->info_2
);
3354 SAFE_FREE(*pp_printer
);
3358 /****************************************************************************
3359 ****************************************************************************/
3360 uint32
add_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver
, uint32 level
)
3363 DEBUG(104,("adding a printer at level [%d]\n", level
));
3364 dump_a_printer_driver(driver
, level
);
3370 result
=add_a_printer_driver_3(driver
.info_3
);
3376 result
=add_a_printer_driver_6(driver
.info_6
);
3386 /****************************************************************************
3387 ****************************************************************************/
3388 WERROR
get_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL
*driver
, uint32 level
,
3389 fstring drivername
, const fstring architecture
, uint32 version
)
3396 /* Sometime we just want any version of the driver */
3398 if ( version
== DRIVER_ANY_VERSION
) {
3399 /* look for Win2k first and then for NT4 */
3400 result
= get_a_printer_driver_3(&driver
->info_3
, drivername
,
3403 if ( !W_ERROR_IS_OK(result
) ) {
3404 result
= get_a_printer_driver_3( &driver
->info_3
,
3405 drivername
, architecture
, 2 );
3409 result
= get_a_printer_driver_3(&driver
->info_3
, drivername
,
3410 architecture
, version
);
3419 if (W_ERROR_IS_OK(result
))
3420 dump_a_printer_driver(*driver
, level
);
3425 /****************************************************************************
3426 ****************************************************************************/
3427 uint32
free_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver
, uint32 level
)
3435 NT_PRINTER_DRIVER_INFO_LEVEL_3
*info3
;
3436 if (driver
.info_3
!= NULL
)
3438 info3
=driver
.info_3
;
3439 SAFE_FREE(info3
->dependentfiles
);
3440 ZERO_STRUCTP(info3
);
3452 NT_PRINTER_DRIVER_INFO_LEVEL_6
*info6
;
3453 if (driver
.info_6
!= NULL
)
3455 info6
=driver
.info_6
;
3456 SAFE_FREE(info6
->dependentfiles
);
3457 SAFE_FREE(info6
->previousnames
);
3458 ZERO_STRUCTP(info6
);
3476 /****************************************************************************
3477 Determine whether or not a particular driver is currently assigned
3479 ****************************************************************************/
3481 BOOL
printer_driver_in_use ( NT_PRINTER_DRIVER_INFO_LEVEL_3
*info_3
)
3484 int n_services
= lp_numservices();
3485 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
3490 DEBUG(5,("printer_driver_in_use: Beginning search through ntprinters.tdb...\n"));
3492 /* loop through the printers.tdb and check for the drivername */
3494 for (snum
=0; snum
<n_services
; snum
++)
3496 if ( !(lp_snum_ok(snum
) && lp_print_ok(snum
) ) )
3499 if ( !W_ERROR_IS_OK(get_a_printer(&printer
, 2, lp_servicename(snum
))) )
3502 if ( !StrCaseCmp(info_3
->name
, printer
->info_2
->drivername
) ) {
3503 free_a_printer( &printer
, 2 );
3507 free_a_printer( &printer
, 2 );
3510 DEBUG(5,("printer_driver_in_use: Completed search through ntprinters.tdb...\n"));
3512 /* report that the driver is not in use by default */
3517 /****************************************************************************
3518 Remove a printer driver from the TDB. This assumes that the the driver was
3519 previously looked up.
3520 ***************************************************************************/
3522 WERROR
delete_printer_driver( NT_PRINTER_DRIVER_INFO_LEVEL_3
*info_3
, struct current_user
*user
,
3523 uint32 version
, BOOL delete_files
)
3527 TDB_DATA kbuf
, dbuf
;
3528 NT_PRINTER_DRIVER_INFO_LEVEL ctr
;
3530 /* delete the tdb data first */
3532 get_short_archi(arch
, info_3
->environment
);
3533 slprintf(key
, sizeof(key
)-1, "%s%s/%d/%s", DRIVERS_PREFIX
,
3534 arch
, version
, info_3
->name
);
3536 DEBUG(5,("delete_printer_driver: key = [%s] delete_files = %s\n",
3537 key
, delete_files
? "TRUE" : "FALSE" ));
3539 ctr
.info_3
= info_3
;
3540 dump_a_printer_driver( ctr
, 3 );
3543 kbuf
.dsize
=strlen(key
)+1;
3545 /* check if the driver actually exists for this environment */
3547 dbuf
= tdb_fetch( tdb_drivers
, kbuf
);
3549 DEBUG(8,("delete_printer_driver: Driver unknown [%s]\n", key
));
3550 return WERR_UNKNOWN_PRINTER_DRIVER
;
3553 SAFE_FREE( dbuf
.dptr
);
3555 /* ok... the driver exists so the delete should return success */
3557 if (tdb_delete(tdb_drivers
, kbuf
) == -1) {
3558 DEBUG (0,("delete_printer_driver: fail to delete %s!\n", key
));
3559 return WERR_ACCESS_DENIED
;
3562 #if 0 /* JERRY - no used in Samba 2.2.x */
3564 * now delete any associated files if delete_files == True
3565 * even if this part failes, we return succes because the
3566 * driver doesn not exist any more
3570 delete_driver_files( i
, user
);
3574 DEBUG(5,("delete_printer_driver: driver delete successful [%s]\n", key
));
3579 /****************************************************************************
3580 ****************************************************************************/
3581 BOOL
get_specific_param_by_index(NT_PRINTER_INFO_LEVEL printer
, uint32 level
, uint32 param_index
,
3582 fstring value
, uint8
**data
, uint32
*type
, uint32
*len
)
3584 /* right now that's enough ! */
3585 NT_PRINTER_PARAM
*param
;
3588 param
=printer
.info_2
->specific
;
3590 while (param
!= NULL
&& i
< param_index
) {
3598 /* exited because it exist */
3600 StrnCpy(value
, param
->value
, sizeof(fstring
)-1);
3601 *data
=(uint8
*)malloc(param
->data_len
*sizeof(uint8
));
3604 ZERO_STRUCTP(*data
);
3605 memcpy(*data
, param
->data
, param
->data_len
);
3606 *len
=param
->data_len
;
3610 /****************************************************************************
3611 ****************************************************************************/
3612 BOOL
get_specific_param(NT_PRINTER_INFO_LEVEL printer
, uint32 level
,
3613 fstring value
, uint8
**data
, uint32
*type
, uint32
*len
)
3615 /* right now that's enough ! */
3616 NT_PRINTER_PARAM
*param
;
3618 DEBUG(10, ("get_specific_param\n"));
3620 param
=printer
.info_2
->specific
;
3622 while (param
!= NULL
)
3624 #if 1 /* JRA - I think this should be case insensitive.... */
3625 if ( strequal(value
, param
->value
)
3627 if ( !strcmp(value
, param
->value
)
3629 && strlen(value
)==strlen(param
->value
))
3637 DEBUGADD(10, ("get_specific_param: found one param\n"));
3638 /* exited because it exist */
3641 *data
=(uint8
*)malloc(param
->data_len
*sizeof(uint8
));
3644 memcpy(*data
, param
->data
, param
->data_len
);
3645 *len
=param
->data_len
;
3647 DEBUGADD(10, ("get_specific_param: exit true\n"));
3650 DEBUGADD(10, ("get_specific_param: exit false\n"));
3654 /****************************************************************************
3655 Store a security desc for a printer.
3656 ****************************************************************************/
3658 WERROR
nt_printing_setsec(char *printername
, SEC_DESC_BUF
*secdesc_ctr
)
3660 SEC_DESC_BUF
*new_secdesc_ctr
= NULL
;
3661 SEC_DESC_BUF
*old_secdesc_ctr
= NULL
;
3663 TALLOC_CTX
*mem_ctx
= NULL
;
3667 mem_ctx
= talloc_init();
3668 if (mem_ctx
== NULL
)
3671 /* The old owner and group sids of the security descriptor are not
3672 present when new ACEs are added or removed by changing printer
3673 permissions through NT. If they are NULL in the new security
3674 descriptor then copy them over from the old one. */
3676 if (!secdesc_ctr
->sec
->owner_sid
|| !secdesc_ctr
->sec
->grp_sid
) {
3677 DOM_SID
*owner_sid
, *group_sid
;
3678 SEC_ACL
*dacl
, *sacl
;
3679 SEC_DESC
*psd
= NULL
;
3682 nt_printing_getsec(mem_ctx
, printername
, &old_secdesc_ctr
);
3684 /* Pick out correct owner and group sids */
3686 owner_sid
= secdesc_ctr
->sec
->owner_sid
?
3687 secdesc_ctr
->sec
->owner_sid
:
3688 old_secdesc_ctr
->sec
->owner_sid
;
3690 group_sid
= secdesc_ctr
->sec
->grp_sid
?
3691 secdesc_ctr
->sec
->grp_sid
:
3692 old_secdesc_ctr
->sec
->grp_sid
;
3694 dacl
= secdesc_ctr
->sec
->dacl
?
3695 secdesc_ctr
->sec
->dacl
:
3696 old_secdesc_ctr
->sec
->dacl
;
3698 sacl
= secdesc_ctr
->sec
->sacl
?
3699 secdesc_ctr
->sec
->sacl
:
3700 old_secdesc_ctr
->sec
->sacl
;
3702 /* Make a deep copy of the security descriptor */
3704 psd
= make_sec_desc(mem_ctx
, secdesc_ctr
->sec
->revision
,
3705 owner_sid
, group_sid
,
3710 new_secdesc_ctr
= make_sec_desc_buf(mem_ctx
, size
, psd
);
3713 if (!new_secdesc_ctr
) {
3714 new_secdesc_ctr
= secdesc_ctr
;
3717 /* Store the security descriptor in a tdb */
3719 prs_init(&ps
, (uint32
)sec_desc_size(new_secdesc_ctr
->sec
) +
3720 sizeof(SEC_DESC_BUF
), mem_ctx
, MARSHALL
);
3722 if (!sec_io_desc_buf("nt_printing_setsec", &new_secdesc_ctr
,
3724 status
= WERR_BADFUNC
;
3728 slprintf(key
, sizeof(key
)-1, "SECDESC/%s", printername
);
3730 if (tdb_prs_store(tdb_printers
, key
, &ps
)==0) {
3733 DEBUG(1,("Failed to store secdesc for %s\n", printername
));
3734 status
= WERR_BADFUNC
;
3737 /* Free malloc'ed memory */
3743 talloc_destroy(mem_ctx
);
3747 /****************************************************************************
3748 Construct a default security descriptor buffer for a printer.
3749 ****************************************************************************/
3751 static SEC_DESC_BUF
*construct_default_printer_sdb(TALLOC_CTX
*ctx
)
3753 extern DOM_SID global_sam_sid
;
3756 SEC_ACL
*psa
= NULL
;
3757 SEC_DESC_BUF
*sdb
= NULL
;
3758 SEC_DESC
*psd
= NULL
;
3761 enum SID_NAME_USE name_type
;
3764 /* Create an ACE where Everyone is allowed to print */
3766 init_sec_access(&sa
, PRINTER_ACE_PRINT
);
3767 init_sec_ace(&ace
[0], &global_sid_World
, SEC_ACE_TYPE_ACCESS_ALLOWED
,
3768 sa
, SEC_ACE_FLAG_CONTAINER_INHERIT
);
3770 /* Make the security descriptor owned by the Administrators group
3771 on the PDC of the domain. */
3773 /* Note that for hysterical raisins, the argument to
3774 secrets_fetch_domain_sid() must be in dos codepage format.
3777 fstrcpy(dos_domain
, lp_workgroup());
3778 unix_to_dos(dos_domain
);
3780 if (secrets_fetch_domain_sid(dos_domain
, &owner_sid
)) {
3781 sid_append_rid(&owner_sid
, DOMAIN_USER_RID_ADMIN
);
3784 /* Backup plan - make printer owned by admins or root.
3785 This should emulate a lanman printer as security
3786 settings can't be changed. */
3788 if (!lookup_name("root", &owner_sid
, &name_type
)) {
3789 sid_copy(&owner_sid
, &global_sam_sid
);
3790 sid_append_rid(&owner_sid
, DOMAIN_USER_RID_ADMIN
);
3794 init_sec_access(&sa
, PRINTER_ACE_FULL_CONTROL
);
3795 init_sec_ace(&ace
[1], &owner_sid
, SEC_ACE_TYPE_ACCESS_ALLOWED
,
3796 sa
, SEC_ACE_FLAG_OBJECT_INHERIT
|
3797 SEC_ACE_FLAG_INHERIT_ONLY
);
3799 init_sec_access(&sa
, PRINTER_ACE_FULL_CONTROL
);
3800 init_sec_ace(&ace
[2], &owner_sid
, SEC_ACE_TYPE_ACCESS_ALLOWED
,
3801 sa
, SEC_ACE_FLAG_CONTAINER_INHERIT
);
3803 /* The ACL revision number in rpc_secdesc.h differs from the one
3804 created by NT when setting ACE entries in printer
3805 descriptors. NT4 complains about the property being edited by a
3808 if ((psa
= make_sec_acl(ctx
, NT4_ACL_REVISION
, 3, ace
)) != NULL
) {
3809 psd
= make_sec_desc(ctx
, SEC_DESC_REVISION
,
3811 NULL
, psa
, &sd_size
);
3815 DEBUG(0,("construct_default_printer_sd: Failed to make SEC_DESC.\n"));
3819 sdb
= make_sec_desc_buf(ctx
, sd_size
, psd
);
3821 DEBUG(4,("construct_default_printer_sdb: size = %u.\n",
3822 (unsigned int)sd_size
));
3827 /****************************************************************************
3828 Get a security desc for a printer.
3829 ****************************************************************************/
3831 BOOL
nt_printing_getsec(TALLOC_CTX
*ctx
, char *printername
, SEC_DESC_BUF
**secdesc_ctr
)
3837 if ((temp
= strchr(printername
+ 2, '\\'))) {
3838 printername
= temp
+ 1;
3841 /* Fetch security descriptor from tdb */
3843 slprintf(key
, sizeof(key
)-1, "SECDESC/%s", printername
);
3845 if (tdb_prs_fetch(tdb_printers
, key
, &ps
, ctx
)!=0 ||
3846 !sec_io_desc_buf("nt_printing_getsec", secdesc_ctr
, &ps
, 1)) {
3848 DEBUG(4,("using default secdesc for %s\n", printername
));
3850 if (!(*secdesc_ctr
= construct_default_printer_sdb(ctx
))) {
3854 /* Save default security descriptor for later */
3856 prs_init(&ps
, (uint32
)sec_desc_size((*secdesc_ctr
)->sec
) +
3857 sizeof(SEC_DESC_BUF
), ctx
, MARSHALL
);
3859 if (sec_io_desc_buf("nt_printing_setsec", secdesc_ctr
, &ps
, 1))
3860 tdb_prs_store(tdb_printers
, key
, &ps
);
3867 /* If security descriptor is owned by S-1-1-0 and winbindd is up,
3868 this security descriptor has been created when winbindd was
3869 down. Take ownership of security descriptor. */
3871 if (sid_equal((*secdesc_ctr
)->sec
->owner_sid
, &global_sid_World
)) {
3873 enum SID_NAME_USE name_type
;
3875 /* Change sd owner to workgroup administrator */
3877 if (winbind_lookup_name(NULL
, lp_workgroup(), &owner_sid
,
3879 SEC_DESC_BUF
*new_secdesc_ctr
= NULL
;
3880 SEC_DESC
*psd
= NULL
;
3885 sid_append_rid(&owner_sid
, DOMAIN_USER_RID_ADMIN
);
3887 psd
= make_sec_desc(ctx
, (*secdesc_ctr
)->sec
->revision
,
3889 (*secdesc_ctr
)->sec
->grp_sid
,
3890 (*secdesc_ctr
)->sec
->sacl
,
3891 (*secdesc_ctr
)->sec
->dacl
,
3894 new_secdesc_ctr
= make_sec_desc_buf(ctx
, size
, psd
);
3896 /* Swap with other one */
3898 *secdesc_ctr
= new_secdesc_ctr
;
3902 nt_printing_setsec(printername
, *secdesc_ctr
);
3906 if (DEBUGLEVEL
>= 10) {
3907 SEC_ACL
*the_acl
= (*secdesc_ctr
)->sec
->dacl
;
3910 DEBUG(10, ("secdesc_ctr for %s has %d aces:\n",
3911 printername
, the_acl
->num_aces
));
3913 for (i
= 0; i
< the_acl
->num_aces
; i
++) {
3916 sid_to_string(sid_str
, &the_acl
->ace
[i
].trustee
);
3918 DEBUG(10, ("%s %d %d 0x%08x\n", sid_str
,
3919 the_acl
->ace
[i
].type
, the_acl
->ace
[i
].flags
,
3920 the_acl
->ace
[i
].info
.mask
));
3930 1: level not implemented
3931 2: file doesn't exist
3932 3: can't allocate memory
3933 4: can't free memory
3934 5: non existant struct
3938 A printer and a printer driver are 2 different things.
3939 NT manages them separatelly, Samba does the same.
3940 Why ? Simply because it's easier and it makes sense !
3942 Now explanation: You have 3 printers behind your samba server,
3943 2 of them are the same make and model (laser A and B). But laser B
3944 has an 3000 sheet feeder and laser A doesn't such an option.
3945 Your third printer is an old dot-matrix model for the accounting :-).
3947 If the /usr/local/samba/lib directory (default dir), you will have
3948 5 files to describe all of this.
3950 3 files for the printers (1 by printer):
3953 NTprinter_accounting
3954 2 files for the drivers (1 for the laser and 1 for the dot matrix)
3955 NTdriver_printer model X
3956 NTdriver_printer model Y
3958 jfm: I should use this comment for the text file to explain
3959 same thing for the forms BTW.
3960 Je devrais mettre mes commentaires en francais, ca serait mieux :-)
3964 /* Convert generic access rights to printer object specific access rights.
3965 It turns out that NT4 security descriptors use generic access rights and
3966 NT5 the object specific ones. */
3968 void map_printer_permissions(SEC_DESC
*sd
)
3972 for (i
= 0; sd
->dacl
&& i
< sd
->dacl
->num_aces
; i
++) {
3973 se_map_generic(&sd
->dacl
->ace
[i
].info
.mask
,
3974 &printer_generic_mapping
);
3978 /****************************************************************************
3979 Check a user has permissions to perform the given operation. We use the
3980 permission constants defined in include/rpc_spoolss.h to check the various
3981 actions we perform when checking printer access.
3983 PRINTER_ACCESS_ADMINISTER:
3984 print_queue_pause, print_queue_resume, update_printer_sec,
3985 update_printer, spoolss_addprinterex_level_2,
3986 _spoolss_setprinterdata
3991 JOB_ACCESS_ADMINISTER:
3992 print_job_delete, print_job_pause, print_job_resume,
3995 ****************************************************************************/
3996 BOOL
print_access_check(struct current_user
*user
, int snum
, int access_type
)
3998 SEC_DESC_BUF
*secdesc
= NULL
;
3999 uint32 access_granted
;
4003 TALLOC_CTX
*mem_ctx
= NULL
;
4004 extern struct current_user current_user
;
4006 /* If user is NULL then use the current_user structure */
4009 user
= ¤t_user
;
4011 /* Always allow root or printer admins to do anything */
4013 if (user
->uid
== 0 ||
4014 user_in_list(uidtoname(user
->uid
), lp_printer_admin(snum
))) {
4018 /* Get printer name */
4020 pname
= PRINTERNAME(snum
);
4022 if (!pname
|| !*pname
) {
4027 /* Get printer security descriptor */
4029 if(!(mem_ctx
= talloc_init())) {
4034 nt_printing_getsec(mem_ctx
, pname
, &secdesc
);
4036 if (access_type
== JOB_ACCESS_ADMINISTER
) {
4037 SEC_DESC_BUF
*parent_secdesc
= secdesc
;
4039 /* Create a child security descriptor to check permissions
4040 against. This is because print jobs are child objects
4041 objects of a printer. */
4043 secdesc
= se_create_child_secdesc(mem_ctx
, parent_secdesc
->sec
, False
);
4045 /* Now this is the bit that really confuses me. The access
4046 type needs to be changed from JOB_ACCESS_ADMINISTER to
4047 PRINTER_ACCESS_ADMINISTER for this to work. Something
4048 to do with the child (job) object becoming like a
4051 access_type
= PRINTER_ACCESS_ADMINISTER
;
4056 map_printer_permissions(secdesc
->sec
);
4058 result
= se_access_check(secdesc
->sec
, user
->nt_user_token
, access_type
,
4059 &access_granted
, &status
);
4061 DEBUG(4, ("access check was %s\n", result
? "SUCCESS" : "FAILURE"));
4063 talloc_destroy(mem_ctx
);
4071 /****************************************************************************
4072 Check the time parameters allow a print operation.
4073 *****************************************************************************/
4075 BOOL
print_time_access_check(int snum
)
4077 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
4079 time_t now
= time(NULL
);
4083 if (!W_ERROR_IS_OK(get_a_printer(&printer
, 2, lp_servicename(snum
))))
4086 if (printer
->info_2
->starttime
== 0 && printer
->info_2
->untiltime
== 0)
4090 mins
= (uint32
)t
->tm_hour
*60 + (uint32
)t
->tm_min
;
4092 if (mins
>= printer
->info_2
->starttime
&& mins
<= printer
->info_2
->untiltime
)
4095 free_a_printer(&printer
, 2);
4103 #if 0 /* JERRY - not used */
4104 /****************************************************************************
4105 Attempt to write a default device.
4106 *****************************************************************************/
4108 WERROR
printer_write_default_dev(int snum
, const PRINTER_DEFAULT
*printer_default
)
4110 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
4114 * Don't bother if no default devicemode was sent.
4117 if (printer_default
->devmode_cont
.devmode
== NULL
)
4120 result
= get_a_printer(&printer
, 2, lp_servicename(snum
));
4121 if (!W_ERROR_IS_OK(result
)) return result
;
4124 * Just ignore it if we already have a devmode.
4127 if (printer
->info_2
->devmode
!= NULL
)
4131 * We don't have a devicemode and we're trying to write
4132 * one. Check we have the access needed.
4134 DEBUG(5,("printer_write_default_dev: access: %x\n", printer_default
->access_required
));
4136 if ( (printer_default
->access_required
& PRINTER_ACCESS_ADMINISTER
) !=
4137 PRINTER_ACCESS_ADMINISTER
) {
4138 DEBUG(5,("printer_write_default_dev: invalid request access to update: %x\n", printer_default
->access_required
));
4139 result
= WERR_ACCESS_DENIED
;
4143 if (!print_access_check(NULL
, snum
, PRINTER_ACCESS_ADMINISTER
)) {
4144 DEBUG(5,("printer_write_default_dev: Access denied for printer %s\n",
4145 lp_servicename(snum
) ));
4146 result
= WERR_ACCESS_DENIED
;
4147 /*result = NT_STATUS_NO_PROBLEMO;*/
4151 DEBUG(5,("printer_write_default_dev: updating, check OK.\n"));
4154 * Convert the on the wire devicemode format to the internal one.
4157 if (!convert_devicemode(printer
->info_2
->printername
,
4158 printer_default
->devmode_cont
.devmode
,
4159 &printer
->info_2
->devmode
)) {
4160 result
= WERR_NOMEM
;
4165 * Finally write back to the tdb.
4168 result
= mod_a_printer(*printer
, 2);
4172 free_a_printer(&printer
, 2);