2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Copyright (C) Andrew Tridgell 1992-2000,
5 * Copyright (C) Jean François Micouleau 1998-2000.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 extern DOM_SID global_sid_World
;
26 static TDB_CONTEXT
*tdb_forms
; /* used for forms files */
27 static TDB_CONTEXT
*tdb_drivers
; /* used for driver files */
28 static TDB_CONTEXT
*tdb_printers
; /* used for printers files */
30 #define FORMS_PREFIX "FORMS/"
31 #define DRIVERS_PREFIX "DRIVERS/"
32 #define DRIVER_INIT_PREFIX "DRIVER_INIT/"
33 #define PRINTERS_PREFIX "PRINTERS/"
34 #define SECDESC_PREFIX "SECDESC/"
35 #define GLOBAL_C_SETPRINTER "GLOBALS/c_setprinter"
37 #define NTDRIVERS_DATABASE_VERSION_1 1
38 #define NTDRIVERS_DATABASE_VERSION_2 2
39 #define NTDRIVERS_DATABASE_VERSION_3 3 /* little endian version of v2 */
41 #define NTDRIVERS_DATABASE_VERSION NTDRIVERS_DATABASE_VERSION_3
43 /* Map generic permissions to printer object specific permissions */
45 GENERIC_MAPPING printer_generic_mapping
= {
52 STANDARD_MAPPING printer_std_mapping
= {
59 /* Map generic permissions to print server object specific permissions */
61 GENERIC_MAPPING printserver_generic_mapping
= {
68 STANDARD_MAPPING printserver_std_mapping
= {
75 /* We need one default form to support our default printer. Msoft adds the
76 forms it wants and in the ORDER it wants them (note: DEVMODE papersize is an
77 array index). Letter is always first, so (for the current code) additions
78 always put things in the correct order. */
79 static nt_forms_struct default_forms
[] = {
80 {"Letter",0x1,0x34b5c,0x44368,0x0,0x0,0x34b5c,0x44368},
81 {"Letter Small",0x1,0x34b5c,0x44368,0x0,0x0,0x34b5c,0x44368},
82 {"Tabloid",0x1,0x44368,0x696b8,0x0,0x0,0x44368,0x696b8},
83 {"Ledger",0x1,0x696b8,0x44368,0x0,0x0,0x696b8,0x44368},
84 {"Legal",0x1,0x34b5c,0x56d10,0x0,0x0,0x34b5c,0x56d10},
85 {"Statement",0x1,0x221b4,0x34b5c,0x0,0x0,0x221b4,0x34b5c},
86 {"Executive",0x1,0x2cf56,0x411cc,0x0,0x0,0x2cf56,0x411cc},
87 {"A3",0x1,0x48828,0x668a0,0x0,0x0,0x48828,0x668a0},
88 {"A4",0x1,0x33450,0x48828,0x0,0x0,0x33450,0x48828},
89 {"A4 Small",0x1,0x33450,0x48828,0x0,0x0,0x33450,0x48828},
90 {"A5",0x1,0x24220,0x33450,0x0,0x0,0x24220,0x33450},
91 {"B4 (JIS)",0x1,0x3ebe8,0x58de0,0x0,0x0,0x3ebe8,0x58de0},
92 {"B5 (JIS)",0x1,0x2c6f0,0x3ebe8,0x0,0x0,0x2c6f0,0x3ebe8},
93 {"Folio",0x1,0x34b5c,0x509d8,0x0,0x0,0x34b5c,0x509d8},
94 {"Quarto",0x1,0x347d8,0x43238,0x0,0x0,0x347d8,0x43238},
95 {"10x14",0x1,0x3e030,0x56d10,0x0,0x0,0x3e030,0x56d10},
96 {"11x17",0x1,0x44368,0x696b8,0x0,0x0,0x44368,0x696b8},
97 {"Note",0x1,0x34b5c,0x44368,0x0,0x0,0x34b5c,0x44368},
98 {"Envelope #9",0x1,0x18079,0x37091,0x0,0x0,0x18079,0x37091},
99 {"Envelope #10",0x1,0x19947,0x3ae94,0x0,0x0,0x19947,0x3ae94},
100 {"Envelope #11",0x1,0x1be7c,0x40565,0x0,0x0,0x1be7c,0x40565},
101 {"Envelope #12",0x1,0x1d74a,0x44368,0x0,0x0,0x1d74a,0x44368},
102 {"Envelope #14",0x1,0x1f018,0x47504,0x0,0x0,0x1f018,0x47504},
103 {"C size sheet",0x1,0x696b8,0x886d0,0x0,0x0,0x696b8,0x886d0},
104 {"D size sheet",0x1,0x886d0,0xd2d70,0x0,0x0,0x886d0,0xd2d70},
105 {"E size sheet",0x1,0xd2d70,0x110da0,0x0,0x0,0xd2d70,0x110da0},
106 {"Envelope DL",0x1,0x1adb0,0x35b60,0x0,0x0,0x1adb0,0x35b60},
107 {"Envelope C5",0x1,0x278d0,0x37e88,0x0,0x0,0x278d0,0x37e88},
108 {"Envelope C3",0x1,0x4f1a0,0x6fd10,0x0,0x0,0x4f1a0,0x6fd10},
109 {"Envelope C4",0x1,0x37e88,0x4f1a0,0x0,0x0,0x37e88,0x4f1a0},
110 {"Envelope C6",0x1,0x1bd50,0x278d0,0x0,0x0,0x1bd50,0x278d0},
111 {"Envelope C65",0x1,0x1bd50,0x37e88,0x0,0x0,0x1bd50,0x37e88},
112 {"Envelope B4",0x1,0x3d090,0x562e8,0x0,0x0,0x3d090,0x562e8},
113 {"Envelope B5",0x1,0x2af80,0x3d090,0x0,0x0,0x2af80,0x3d090},
114 {"Envelope B6",0x1,0x2af80,0x1e848,0x0,0x0,0x2af80,0x1e848},
115 {"Envelope",0x1,0x1adb0,0x38270,0x0,0x0,0x1adb0,0x38270},
116 {"Envelope Monarch",0x1,0x18079,0x2e824,0x0,0x0,0x18079,0x2e824},
117 {"6 3/4 Envelope",0x1,0x167ab,0x284ec,0x0,0x0,0x167ab,0x284ec},
118 {"US Std Fanfold",0x1,0x5c3e1,0x44368,0x0,0x0,0x5c3e1,0x44368},
119 {"German Std Fanfold",0x1,0x34b5c,0x4a6a0,0x0,0x0,0x34b5c,0x4a6a0},
120 {"German Legal Fanfold",0x1,0x34b5c,0x509d8,0x0,0x0,0x34b5c,0x509d8},
121 {"B4 (ISO)",0x1,0x3d090,0x562e8,0x0,0x0,0x3d090,0x562e8},
122 {"Japanese Postcard",0x1,0x186a0,0x24220,0x0,0x0,0x186a0,0x24220},
123 {"9x11",0x1,0x37cf8,0x44368,0x0,0x0,0x37cf8,0x44368},
124 {"10x11",0x1,0x3e030,0x44368,0x0,0x0,0x3e030,0x44368},
125 {"15x11",0x1,0x5d048,0x44368,0x0,0x0,0x5d048,0x44368},
126 {"Envelope Invite",0x1,0x35b60,0x35b60,0x0,0x0,0x35b60,0x35b60},
127 {"Reserved48",0x1,0x1,0x1,0x0,0x0,0x1,0x1},
128 {"Reserved49",0x1,0x1,0x1,0x0,0x0,0x1,0x1},
129 {"Letter Extra",0x1,0x3ae94,0x4a6a0,0x0,0x0,0x3ae94,0x4a6a0},
130 {"Legal Extra",0x1,0x3ae94,0x5d048,0x0,0x0,0x3ae94,0x5d048},
131 {"Tabloid Extra",0x1,0x4a6a0,0x6f9f0,0x0,0x0,0x4a6a0,0x6f9f0},
132 {"A4 Extra",0x1,0x397c2,0x4eb16,0x0,0x0,0x397c2,0x4eb16},
133 {"Letter Transverse",0x1,0x34b5c,0x44368,0x0,0x0,0x34b5c,0x44368},
134 {"A4 Transverse",0x1,0x33450,0x48828,0x0,0x0,0x33450,0x48828},
135 {"Letter Extra Transverse",0x1,0x3ae94,0x4a6a0,0x0,0x0,0x3ae94,0x4a6a0},
136 {"Super A",0x1,0x376b8,0x56ea0,0x0,0x0,0x376b8,0x56ea0},
137 {"Super B",0x1,0x4a768,0x76e58,0x0,0x0,0x4a768,0x76e58},
138 {"Letter Plus",0x1,0x34b5c,0x4eb16,0x0,0x0,0x34b5c,0x4eb16},
139 {"A4 Plus",0x1,0x33450,0x50910,0x0,0x0,0x33450,0x50910},
140 {"A5 Transverse",0x1,0x24220,0x33450,0x0,0x0,0x24220,0x33450},
141 {"B5 (JIS) Transverse",0x1,0x2c6f0,0x3ebe8,0x0,0x0,0x2c6f0,0x3ebe8},
142 {"A3 Extra",0x1,0x4e9d0,0x6ca48,0x0,0x0,0x4e9d0,0x6ca48},
143 {"A5 Extra",0x1,0x2a7b0,0x395f8,0x0,0x0,0x2a7b0,0x395f8},
144 {"B5 (ISO) Extra",0x1,0x31128,0x43620,0x0,0x0,0x31128,0x43620},
145 {"A2",0x1,0x668a0,0x91050,0x0,0x0,0x668a0,0x91050},
146 {"A3 Transverse",0x1,0x48828,0x668a0,0x0,0x0,0x48828,0x668a0},
147 {"A3 Extra Transverse",0x1,0x4e9d0,0x6ca48,0x0,0x0,0x4e9d0,0x6ca48},
148 {"Japanese Double Postcard",0x1,0x30d40,0x24220,0x0,0x0,0x30d40,0x24220},
149 {"A6",0x1,0x19a28,0x24220,0x0,0x0,0x19a28,0x24220},
150 {"Japanese Envelope Kaku #2",0x1,0x3a980,0x510e0,0x0,0x0,0x3a980,0x510e0},
151 {"Japanese Envelope Kaku #3",0x1,0x34bc0,0x43a08,0x0,0x0,0x34bc0,0x43a08},
152 {"Japanese Envelope Chou #3",0x1,0x1d4c0,0x395f8,0x0,0x0,0x1d4c0,0x395f8},
153 {"Japanese Envelope Chou #4",0x1,0x15f90,0x320c8,0x0,0x0,0x15f90,0x320c8},
154 {"Letter Rotated",0x1,0x44368,0x34b5c,0x0,0x0,0x44368,0x34b5c},
155 {"A3 Rotated",0x1,0x668a0,0x48828,0x0,0x0,0x668a0,0x48828},
156 {"A4 Rotated",0x1,0x48828,0x33450,0x0,0x0,0x48828,0x33450},
157 {"A5 Rotated",0x1,0x33450,0x24220,0x0,0x0,0x33450,0x24220},
158 {"B4 (JIS) Rotated",0x1,0x58de0,0x3ebe8,0x0,0x0,0x58de0,0x3ebe8},
159 {"B5 (JIS) Rotated",0x1,0x3ebe8,0x2c6f0,0x0,0x0,0x3ebe8,0x2c6f0},
160 {"Japanese Postcard Rotated",0x1,0x24220,0x186a0,0x0,0x0,0x24220,0x186a0},
161 {"Double Japan Postcard Rotated",0x1,0x24220,0x30d40,0x0,0x0,0x24220,0x30d40},
162 {"A6 Rotated",0x1,0x24220,0x19a28,0x0,0x0,0x24220,0x19a28},
163 {"Japan Envelope Kaku #2 Rotated",0x1,0x510e0,0x3a980,0x0,0x0,0x510e0,0x3a980},
164 {"Japan Envelope Kaku #3 Rotated",0x1,0x43a08,0x34bc0,0x0,0x0,0x43a08, 0x34bc0},
165 {"Japan Envelope Chou #3 Rotated",0x1,0x395f8,0x1d4c0,0x0,0x0,0x395f8,0x1d4c0},
166 {"Japan Envelope Chou #4 Rotated",0x1,0x320c8,0x15f90,0x0,0x0,0x320c8,0x15f90},
167 {"B6 (JIS)",0x1,0x1f400,0x2c6f0,0x0,0x0,0x1f400,0x2c6f0},
168 {"B6 (JIS) Rotated",0x1,0x2c6f0,0x1f400,0x0,0x0,0x2c6f0,0x1f400},
169 {"12x11",0x1,0x4a724,0x443e1,0x0,0x0,0x4a724,0x443e1},
170 {"Japan Envelope You #4",0x1,0x19a28,0x395f8,0x0,0x0,0x19a28,0x395f8},
171 {"Japan Envelope You #4 Rotated",0x1,0x395f8,0x19a28,0x0,0x0,0x395f8,0x19a28},
172 {"PRC 16K",0x1,0x2de60,0x3f7a0,0x0,0x0,0x2de60,0x3f7a0},
173 {"PRC 32K",0x1,0x1fbd0,0x2cec0,0x0,0x0,0x1fbd0,0x2cec0},
174 {"PRC 32K(Big)",0x1,0x222e0,0x318f8,0x0,0x0,0x222e0,0x318f8},
175 {"PRC Envelope #1",0x1,0x18e70,0x28488,0x0,0x0,0x18e70,0x28488},
176 {"PRC Envelope #2",0x1,0x18e70,0x2af80,0x0,0x0,0x18e70,0x2af80},
177 {"PRC Envelope #3",0x1,0x1e848,0x2af80,0x0,0x0,0x1e848,0x2af80},
178 {"PRC Envelope #4",0x1,0x1adb0,0x32c80,0x0,0x0,0x1adb0,0x32c80},
179 {"PRC Envelope #5",0x1,0x1adb0,0x35b60,0x0,0x0,0x1adb0,0x35b60},
180 {"PRC Envelope #6",0x1,0x1d4c0,0x38270,0x0,0x0,0x1d4c0,0x38270},
181 {"PRC Envelope #7",0x1,0x27100,0x38270,0x0,0x0,0x27100,0x38270},
182 {"PRC Envelope #8",0x1,0x1d4c0,0x4b708,0x0,0x0,0x1d4c0,0x4b708},
183 {"PRC Envelope #9",0x1,0x37e88,0x4f1a0,0x0,0x0,0x37e88,0x4f1a0},
184 {"PRC Envelope #10",0x1,0x4f1a0,0x6fd10,0x0,0x0,0x4f1a0,0x6fd10},
185 {"PRC 16K Rotated",0x1,0x3f7a0,0x2de60,0x0,0x0,0x3f7a0,0x2de60},
186 {"PRC 32K Rotated",0x1,0x2cec0,0x1fbd0,0x0,0x0,0x2cec0,0x1fbd0},
187 {"PRC 32K(Big) Rotated",0x1,0x318f8,0x222e0,0x0,0x0,0x318f8,0x222e0},
188 {"PRC Envelope #1 Rotated",0x1,0x28488,0x18e70,0x0,0x0,0x28488,0x18e70},
189 {"PRC Envelope #2 Rotated",0x1,0x2af80,0x18e70,0x0,0x0,0x2af80,0x18e70},
190 {"PRC Envelope #3 Rotated",0x1,0x2af80,0x1e848,0x0,0x0,0x2af80,0x1e848},
191 {"PRC Envelope #4 Rotated",0x1,0x32c80,0x1adb0,0x0,0x0,0x32c80,0x1adb0},
192 {"PRC Envelope #5 Rotated",0x1,0x35b60,0x1adb0,0x0,0x0,0x35b60,0x1adb0},
193 {"PRC Envelope #6 Rotated",0x1,0x38270,0x1d4c0,0x0,0x0,0x38270,0x1d4c0},
194 {"PRC Envelope #7 Rotated",0x1,0x38270,0x27100,0x0,0x0,0x38270,0x27100},
195 {"PRC Envelope #8 Rotated",0x1,0x4b708,0x1d4c0,0x0,0x0,0x4b708,0x1d4c0},
196 {"PRC Envelope #9 Rotated",0x1,0x4f1a0,0x37e88,0x0,0x0,0x4f1a0,0x37e88},
197 {"PRC Envelope #10 Rotated",0x1,0x6fd10,0x4f1a0,0x0,0x0,0x6fd10,0x4f1a0}
200 static BOOL
upgrade_to_version_3(void)
202 TDB_DATA kbuf
, newkey
, dbuf
;
204 DEBUG(0,("upgrade_to_version_3: upgrading print tdb's to version 3\n"));
206 for (kbuf
= tdb_firstkey(tdb_drivers
); kbuf
.dptr
;
207 newkey
= tdb_nextkey(tdb_drivers
, kbuf
), safe_free(kbuf
.dptr
), kbuf
=newkey
) {
209 dbuf
= tdb_fetch(tdb_drivers
, kbuf
);
211 if (strncmp(kbuf
.dptr
, FORMS_PREFIX
, strlen(FORMS_PREFIX
)) == 0) {
212 DEBUG(0,("upgrade_to_version_3:moving form\n"));
213 if (tdb_store(tdb_forms
, kbuf
, dbuf
, TDB_REPLACE
) != 0) {
214 DEBUG(0,("upgrade_to_version_3: failed to move form. Error (%s).\n", tdb_errorstr(tdb_forms
)));
217 if (tdb_delete(tdb_drivers
, kbuf
) != 0) {
218 DEBUG(0,("upgrade_to_version_3: failed to delete form. Error (%s)\n", tdb_errorstr(tdb_drivers
)));
223 if (strncmp(kbuf
.dptr
, PRINTERS_PREFIX
, strlen(PRINTERS_PREFIX
)) == 0) {
224 DEBUG(0,("upgrade_to_version_3:moving printer\n"));
225 if (tdb_store(tdb_printers
, kbuf
, dbuf
, TDB_REPLACE
) != 0) {
226 DEBUG(0,("upgrade_to_version_3: failed to move printer. Error (%s)\n", tdb_errorstr(tdb_printers
)));
229 if (tdb_delete(tdb_drivers
, kbuf
) != 0) {
230 DEBUG(0,("upgrade_to_version_3: failed to delete printer. Error (%s)\n", tdb_errorstr(tdb_drivers
)));
235 if (strncmp(kbuf
.dptr
, SECDESC_PREFIX
, strlen(SECDESC_PREFIX
)) == 0) {
236 DEBUG(0,("upgrade_to_version_3:moving secdesc\n"));
237 if (tdb_store(tdb_printers
, kbuf
, dbuf
, TDB_REPLACE
) != 0) {
238 DEBUG(0,("upgrade_to_version_3: failed to move secdesc. Error (%s)\n", tdb_errorstr(tdb_printers
)));
241 if (tdb_delete(tdb_drivers
, kbuf
) != 0) {
242 DEBUG(0,("upgrade_to_version_3: failed to delete secdesc. Error (%s)\n", tdb_errorstr(tdb_drivers
)));
247 SAFE_FREE(dbuf
.dptr
);
253 /****************************************************************************
254 Open the NT printing tdb.
255 ****************************************************************************/
257 BOOL
nt_printing_init(void)
259 static pid_t local_pid
;
260 char *vstring
= "INFO/version";
262 if (tdb_drivers
&& tdb_printers
&& tdb_forms
&& local_pid
== sys_getpid())
265 tdb_drivers
= tdb_open_log(lock_path("ntdrivers.tdb"), 0, TDB_DEFAULT
, O_RDWR
|O_CREAT
, 0600);
267 DEBUG(0,("nt_printing_init: Failed to open nt drivers database %s (%s)\n",
268 lock_path("ntdrivers.tdb"), strerror(errno
) ));
272 tdb_printers
= tdb_open_log(lock_path("ntprinters.tdb"), 0, TDB_DEFAULT
, O_RDWR
|O_CREAT
, 0600);
274 DEBUG(0,("nt_printing_init: Failed to open nt printers database %s (%s)\n",
275 lock_path("ntprinters.tdb"), strerror(errno
) ));
279 tdb_forms
= tdb_open_log(lock_path("ntforms.tdb"), 0, TDB_DEFAULT
, O_RDWR
|O_CREAT
, 0600);
281 DEBUG(0,("nt_printing_init: Failed to open nt forms database %s (%s)\n",
282 lock_path("ntforms.tdb"), strerror(errno
) ));
286 local_pid
= sys_getpid();
288 /* handle a Samba upgrade */
289 tdb_lock_bystring(tdb_drivers
, vstring
);
293 /* Cope with byte-reversed older versions of the db. */
294 vers_id
= tdb_fetch_int32(tdb_drivers
, vstring
);
295 if ((vers_id
== NTDRIVERS_DATABASE_VERSION_2
) || (IREV(vers_id
) == NTDRIVERS_DATABASE_VERSION_2
)) {
296 /* Written on a bigendian machine with old fetch_int code. Save as le. */
297 /* The only upgrade between V2 and V3 is to save the version in little-endian. */
298 tdb_store_int32(tdb_drivers
, vstring
, NTDRIVERS_DATABASE_VERSION
);
299 vers_id
= NTDRIVERS_DATABASE_VERSION
;
302 if (vers_id
!= NTDRIVERS_DATABASE_VERSION
) {
304 if ((vers_id
== NTDRIVERS_DATABASE_VERSION_1
) || (IREV(vers_id
) == NTDRIVERS_DATABASE_VERSION_1
)) {
305 if (!upgrade_to_version_3())
308 tdb_traverse(tdb_drivers
, tdb_traverse_delete_fn
, NULL
);
310 tdb_store_int32(tdb_drivers
, vstring
, NTDRIVERS_DATABASE_VERSION
);
313 tdb_unlock_bystring(tdb_drivers
, vstring
);
315 update_c_setprinter(True
);
318 * register callback to handle updating printers as new
319 * drivers are installed
321 message_register(MSG_PRINTER_DRVUPGRADE
, do_drv_upgrade_printer
);
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
);
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 ****************************************************************************/
647 BOOL
get_short_archi(char *short_archi
, char *long_archi
)
654 struct table archi_table
[]=
656 {"Windows 4.0", "WIN40" },
657 {"Windows NT x86", "W32X86" },
658 {"Windows NT R4000", "W32MIPS" },
659 {"Windows NT Alpha_AXP", "W32ALPHA" },
660 {"Windows NT PowerPC", "W32PPC" },
666 DEBUG(107,("Getting architecture dependant directory\n"));
669 } while ( (archi_table
[i
].long_archi
!=NULL
) &&
670 StrCaseCmp(long_archi
, archi_table
[i
].long_archi
) );
672 if (archi_table
[i
].long_archi
==NULL
) {
673 DEBUGADD(107,("Unknown architecture [%s] !\n", long_archi
));
677 StrnCpy (short_archi
, archi_table
[i
].short_archi
, strlen(archi_table
[i
].short_archi
));
679 DEBUGADD(108,("index: [%d]\n", i
));
680 DEBUGADD(108,("long architecture: [%s]\n", long_archi
));
681 DEBUGADD(108,("short architecture: [%s]\n", short_archi
));
686 /****************************************************************************
687 Version information in Microsoft files is held in a VS_VERSION_INFO structure.
688 There are two case to be covered here: PE (Portable Executable) and NE (New
689 Executable) files. Both files support the same INFO structure, but PE files
690 store the signature in unicode, and NE files store it as !unicode.
691 returns -1 on error, 1 on version info found, and 0 on no version info found.
692 ****************************************************************************/
694 static int get_file_version(files_struct
*fsp
, char *fname
,uint32
*major
, uint32
*minor
)
700 if ((buf
=malloc(PE_HEADER_SIZE
)) == NULL
) {
701 DEBUG(0,("get_file_version: PE file [%s] PE Header malloc failed bytes = %d\n",
702 fname
, PE_HEADER_SIZE
));
706 /* Note: DOS_HEADER_SIZE < malloc'ed PE_HEADER_SIZE */
707 if ((byte_count
= vfs_read_data(fsp
, buf
, DOS_HEADER_SIZE
)) < DOS_HEADER_SIZE
) {
708 DEBUG(3,("get_file_version: File [%s] DOS header too short, bytes read = %d\n",
710 goto no_version_info
;
713 /* Is this really a DOS header? */
714 if (SVAL(buf
,DOS_HEADER_MAGIC_OFFSET
) != DOS_HEADER_MAGIC
) {
715 DEBUG(6,("get_file_version: File [%s] bad DOS magic = 0x%x\n",
716 fname
, SVAL(buf
,DOS_HEADER_MAGIC_OFFSET
)));
717 goto no_version_info
;
720 /* Skip OEM header (if any) and the DOS stub to start of Windows header */
721 if (fsp
->conn
->vfs_ops
.lseek(fsp
, fsp
->fd
, SVAL(buf
,DOS_HEADER_LFANEW_OFFSET
), SEEK_SET
) == (SMB_OFF_T
)-1) {
722 DEBUG(3,("get_file_version: File [%s] too short, errno = %d\n",
724 /* Assume this isn't an error... the file just looks sort of like a PE/NE file */
725 goto no_version_info
;
728 if ((byte_count
= vfs_read_data(fsp
, buf
, PE_HEADER_SIZE
)) < PE_HEADER_SIZE
) {
729 DEBUG(3,("get_file_version: File [%s] Windows header too short, bytes read = %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 /* The header may be a PE (Portable Executable) or an NE (New Executable) */
736 if (IVAL(buf
,PE_HEADER_SIGNATURE_OFFSET
) == PE_HEADER_SIGNATURE
) {
738 int section_table_bytes
;
740 if (SVAL(buf
,PE_HEADER_MACHINE_OFFSET
) != PE_HEADER_MACHINE_I386
) {
741 DEBUG(3,("get_file_version: PE file [%s] wrong machine = 0x%x\n",
742 fname
, SVAL(buf
,PE_HEADER_MACHINE_OFFSET
)));
743 /* At this point, we assume the file is in error. It still could be somthing
744 * else besides a PE file, but it unlikely at this point.
749 /* get the section table */
750 num_sections
= SVAL(buf
,PE_HEADER_NUMBER_OF_SECTIONS
);
751 section_table_bytes
= num_sections
* PE_HEADER_SECT_HEADER_SIZE
;
753 if ((buf
=malloc(section_table_bytes
)) == NULL
) {
754 DEBUG(0,("get_file_version: PE file [%s] section table malloc failed bytes = %d\n",
755 fname
, section_table_bytes
));
759 if ((byte_count
= vfs_read_data(fsp
, buf
, section_table_bytes
)) < section_table_bytes
) {
760 DEBUG(3,("get_file_version: PE file [%s] Section header too short, bytes read = %d\n",
765 /* Iterate the section table looking for the resource section ".rsrc" */
766 for (i
= 0; i
< num_sections
; i
++) {
767 int sec_offset
= i
* PE_HEADER_SECT_HEADER_SIZE
;
769 if (strcmp(".rsrc", &buf
[sec_offset
+PE_HEADER_SECT_NAME_OFFSET
]) == 0) {
770 int section_pos
= IVAL(buf
,sec_offset
+PE_HEADER_SECT_PTR_DATA_OFFSET
);
771 int section_bytes
= IVAL(buf
,sec_offset
+PE_HEADER_SECT_SIZE_DATA_OFFSET
);
774 if ((buf
=malloc(section_bytes
)) == NULL
) {
775 DEBUG(0,("get_file_version: PE file [%s] version malloc failed bytes = %d\n",
776 fname
, section_bytes
));
780 /* Seek to the start of the .rsrc section info */
781 if (fsp
->conn
->vfs_ops
.lseek(fsp
, fsp
->fd
, section_pos
, SEEK_SET
) == (SMB_OFF_T
)-1) {
782 DEBUG(3,("get_file_version: PE file [%s] too short for section info, errno = %d\n",
787 if ((byte_count
= vfs_read_data(fsp
, buf
, section_bytes
)) < section_bytes
) {
788 DEBUG(3,("get_file_version: PE file [%s] .rsrc section too short, bytes read = %d\n",
793 for (i
=0; i
<section_bytes
-VS_VERSION_INFO_UNICODE_SIZE
; i
++) {
794 /* Scan for 1st 3 unicoded bytes followed by word aligned magic value */
795 if (buf
[i
] == 'V' && buf
[i
+1] == '\0' && buf
[i
+2] == 'S') {
796 /* Align to next long address */
797 int pos
= (i
+ sizeof(VS_SIGNATURE
)*2 + 3) & 0xfffffffc;
799 if (IVAL(buf
,pos
) == VS_MAGIC_VALUE
) {
800 *major
= IVAL(buf
,pos
+VS_MAJOR_OFFSET
);
801 *minor
= IVAL(buf
,pos
+VS_MINOR_OFFSET
);
803 DEBUG(6,("get_file_version: PE file [%s] Version = %08x:%08x (%d.%d.%d.%d)\n",
804 fname
, *major
, *minor
,
805 (*major
>>16)&0xffff, *major
&0xffff,
806 (*minor
>>16)&0xffff, *minor
&0xffff));
815 /* Version info not found, fall back to origin date/time */
816 DEBUG(10,("get_file_version: PE file [%s] has no version info\n", fname
));
820 } else if (SVAL(buf
,NE_HEADER_SIGNATURE_OFFSET
) == NE_HEADER_SIGNATURE
) {
821 if (CVAL(buf
,NE_HEADER_TARGET_OS_OFFSET
) != NE_HEADER_TARGOS_WIN
) {
822 DEBUG(3,("get_file_version: NE file [%s] wrong target OS = 0x%x\n",
823 fname
, CVAL(buf
,NE_HEADER_TARGET_OS_OFFSET
)));
824 /* At this point, we assume the file is in error. It still could be somthing
825 * else besides a NE file, but it unlikely at this point. */
829 /* Allocate a bit more space to speed up things */
831 if ((buf
=malloc(VS_NE_BUF_SIZE
)) == NULL
) {
832 DEBUG(0,("get_file_version: NE file [%s] malloc failed bytes = %d\n",
833 fname
, PE_HEADER_SIZE
));
837 /* This is a HACK! I got tired of trying to sort through the messy
838 * 'NE' file format. If anyone wants to clean this up please have at
839 * it, but this works. 'NE' files will eventually fade away. JRR */
840 while((byte_count
= vfs_read_data(fsp
, buf
, VS_NE_BUF_SIZE
)) > 0) {
841 /* Cover case that should not occur in a well formed 'NE' .dll file */
842 if (byte_count
-VS_VERSION_INFO_SIZE
<= 0) break;
844 for(i
=0; i
<byte_count
; i
++) {
845 /* Fast skip past data that can't possibly match */
846 if (buf
[i
] != 'V') continue;
848 /* Potential match data crosses buf boundry, move it to beginning
849 * of buf, and fill the buf with as much as it will hold. */
850 if (i
>byte_count
-VS_VERSION_INFO_SIZE
) {
853 memcpy(buf
, &buf
[i
], byte_count
-i
);
854 if ((bc
= vfs_read_data(fsp
, &buf
[byte_count
-i
], VS_NE_BUF_SIZE
-
855 (byte_count
-i
))) < 0) {
857 DEBUG(0,("get_file_version: NE file [%s] Read error, errno=%d\n",
862 byte_count
= bc
+ (byte_count
- i
);
863 if (byte_count
<VS_VERSION_INFO_SIZE
) break;
868 /* Check that the full signature string and the magic number that
869 * follows exist (not a perfect solution, but the chances that this
870 * occurs in code is, well, remote. Yes I know I'm comparing the 'V'
871 * twice, as it is simpler to read the code. */
872 if (strcmp(&buf
[i
], VS_SIGNATURE
) == 0) {
873 /* Compute skip alignment to next long address */
874 int skip
= -(fsp
->conn
->vfs_ops
.lseek(fsp
, fsp
->fd
, 0, SEEK_CUR
) - (byte_count
- i
) +
875 sizeof(VS_SIGNATURE
)) & 3;
876 if (IVAL(buf
,i
+sizeof(VS_SIGNATURE
)+skip
) != 0xfeef04bd) continue;
878 *major
= IVAL(buf
,i
+sizeof(VS_SIGNATURE
)+skip
+VS_MAJOR_OFFSET
);
879 *minor
= IVAL(buf
,i
+sizeof(VS_SIGNATURE
)+skip
+VS_MINOR_OFFSET
);
880 DEBUG(6,("get_file_version: NE file [%s] Version = %08x:%08x (%d.%d.%d.%d)\n",
881 fname
, *major
, *minor
,
882 (*major
>>16)&0xffff, *major
&0xffff,
883 (*minor
>>16)&0xffff, *minor
&0xffff));
890 /* Version info not found, fall back to origin date/time */
891 DEBUG(0,("get_file_version: NE file [%s] Version info not found\n", fname
));
896 /* Assume this isn't an error... the file just looks sort of like a PE/NE file */
897 DEBUG(3,("get_file_version: File [%s] unknown file format, signature = 0x%x\n",
898 fname
, IVAL(buf
,PE_HEADER_SIGNATURE_OFFSET
)));
909 /****************************************************************************
910 Drivers for Microsoft systems contain multiple files. Often, multiple drivers
911 share one or more files. During the MS installation process files are checked
912 to insure that only a newer version of a shared file is installed over an
913 older version. There are several possibilities for this comparison. If there
914 is no previous version, the new one is newer (obviously). If either file is
915 missing the version info structure, compare the creation date (on Unix use
916 the modification date). Otherwise chose the numerically larger version number.
917 ****************************************************************************/
918 static int file_version_is_newer(connection_struct
*conn
, fstring new_file
,
921 BOOL use_version
= True
;
926 time_t new_create_time
;
930 time_t old_create_time
;
934 files_struct
*fsp
= NULL
;
936 SMB_STRUCT_STAT stat_buf
;
940 ZERO_STRUCT(stat_buf
);
941 new_create_time
= (time_t)0;
942 old_create_time
= (time_t)0;
944 /* Get file version info (if available) for previous file (if it exists) */
945 pstrcpy(filepath
, old_file
);
947 unix_convert(filepath
,conn
,NULL
,&bad_path
,&stat_buf
);
949 fsp
= open_file_shared(conn
, filepath
, &stat_buf
,
950 SET_OPEN_MODE(DOS_OPEN_RDONLY
),
951 (FILE_FAIL_IF_NOT_EXIST
|FILE_EXISTS_OPEN
),
952 0, 0, &access_mode
, &action
);
954 /* Old file not found, so by definition new file is in fact newer */
955 DEBUG(10,("file_version_is_newer: Can't open old file [%s], errno = %d\n",
960 int ret
= get_file_version(fsp
, old_file
, &old_major
, &old_minor
);
961 if (ret
== -1) goto error_exit
;
964 DEBUG(6,("file_version_is_newer: Version info not found [%s], use mod time\n",
968 if (fsp
->conn
->vfs_ops
.fstat(fsp
, fsp
->fd
, &st
) == -1) goto error_exit
;
969 old_create_time
= st
.st_mtime
;
970 DEBUGADD(6,("file_version_is_newer: mod time = %ld sec\n", old_create_time
));
972 close_file(fsp
, True
);
974 /* Get file version info (if available) for new file */
975 pstrcpy(filepath
, new_file
);
976 unix_convert(filepath
,conn
,NULL
,&bad_path
,&stat_buf
);
978 fsp
= open_file_shared(conn
, filepath
, &stat_buf
,
979 SET_OPEN_MODE(DOS_OPEN_RDONLY
),
980 (FILE_FAIL_IF_NOT_EXIST
|FILE_EXISTS_OPEN
),
981 0, 0, &access_mode
, &action
);
983 /* New file not found, this shouldn't occur if the caller did its job */
984 DEBUG(3,("file_version_is_newer: Can't open new file [%s], errno = %d\n",
989 int ret
= get_file_version(fsp
, new_file
, &new_major
, &new_minor
);
990 if (ret
== -1) goto error_exit
;
993 DEBUG(6,("file_version_is_newer: Version info not found [%s], use mod time\n",
997 if (fsp
->conn
->vfs_ops
.fstat(fsp
, fsp
->fd
, &st
) == -1) goto error_exit
;
998 new_create_time
= st
.st_mtime
;
999 DEBUGADD(6,("file_version_is_newer: mod time = %ld sec\n", new_create_time
));
1001 close_file(fsp
, True
);
1003 if (use_version
&& (new_major
!= old_major
|| new_minor
!= old_minor
)) {
1004 /* Compare versions and choose the larger version number */
1005 if (new_major
> old_major
||
1006 (new_major
== old_major
&& new_minor
> old_minor
)) {
1008 DEBUG(6,("file_version_is_newer: Replacing [%s] with [%s]\n", old_file
, new_file
));
1012 DEBUG(6,("file_version_is_newer: Leaving [%s] unchanged\n", old_file
));
1017 /* Compare modification time/dates and choose the newest time/date */
1018 if (new_create_time
> old_create_time
) {
1019 DEBUG(6,("file_version_is_newer: Replacing [%s] with [%s]\n", old_file
, new_file
));
1023 DEBUG(6,("file_version_is_newer: Leaving [%s] unchanged\n", old_file
));
1030 close_file(fsp
, True
);
1034 /****************************************************************************
1035 Determine the correct cVersion associated with an architecture and driver
1036 ****************************************************************************/
1037 static uint32
get_correct_cversion(fstring architecture
, fstring driverpath_in
,
1038 struct current_user
*user
, WERROR
*perr
)
1046 files_struct
*fsp
= NULL
;
1050 struct passwd
*pass
;
1051 connection_struct
*conn
;
1055 *perr
= WERR_INVALID_PARAM
;
1057 /* If architecture is Windows 95/98/ME, the version is always 0. */
1058 if (strcmp(architecture
, "WIN40") == 0) {
1059 DEBUG(10,("get_correct_cversion: Driver is Win9x, cversion = 0\n"));
1065 pass
= sys_getpwuid(user
->uid
);
1067 DEBUG(0,("get_correct_cversion: Unable to get passwd entry for uid %u\n",
1068 (unsigned int)user
->uid
));
1070 *perr
= WERR_ACCESS_DENIED
;
1075 * Connect to the print$ share under the same account as the user connected
1076 * to the rpc pipe. Note we must still be root to do this.
1079 fstrcpy(user_name
, pass
->pw_name
);
1080 DEBUG(10,("get_correct_cversion: uid %d -> user %s\n", (int)user
->uid
, user_name
));
1082 /* Null password is ok - we are already an authenticated user... */
1084 conn
= make_connection("print$", user_name
, null_pw
, 0, "A:", user
->vuid
, &ecode
);
1088 DEBUG(0,("get_correct_cversion: Unable to connect\n"));
1089 *perr
= W_ERROR(ecode
);
1093 /* We are temporarily becoming the connection user. */
1094 if (!become_user(conn
, conn
->vuid
)) {
1095 DEBUG(0,("get_correct_cversion: Can't become user!\n"));
1096 *perr
= WERR_ACCESS_DENIED
;
1100 /* Open the driver file (Portable Executable format) and determine the
1101 * deriver the cversion. */
1102 slprintf(driverpath
, sizeof(driverpath
)-1, "%s/%s", architecture
, driverpath_in
);
1104 unix_convert(driverpath
,conn
,NULL
,&bad_path
,&st
);
1106 fsp
= open_file_shared(conn
, driverpath
, &st
,
1107 SET_OPEN_MODE(DOS_OPEN_RDONLY
),
1108 (FILE_FAIL_IF_NOT_EXIST
|FILE_EXISTS_OPEN
),
1109 0, 0, &access_mode
, &action
);
1111 DEBUG(3,("get_correct_cversion: Can't open file [%s], errno = %d\n",
1112 driverpath
, errno
));
1113 *perr
= WERR_ACCESS_DENIED
;
1119 int ret
= get_file_version(fsp
, driverpath
, &major
, &minor
);
1120 if (ret
== -1) goto error_exit
;
1123 DEBUG(6,("get_correct_cversion: Version info not found [%s]\n", driverpath
));
1128 * This is a Microsoft'ism. See references in MSDN to VER_FILEVERSION
1129 * for more details. Version in this case is not just the version of the
1130 * file, but the version in the sense of kernal mode (2) vs. user mode
1131 * (3) drivers. Other bits of the version fields are the version info.
1134 cversion
= major
& 0x0000ffff;
1136 case 2: /* WinNT drivers */
1137 case 3: /* Win2K drivers */
1141 DEBUG(6,("get_correct_cversion: cversion invalid [%s] cversion = %d\n",
1142 driverpath
, cversion
));
1146 DEBUG(10,("get_correct_cversion: Version info found [%s] major = 0x%x minor = 0x%x\n",
1147 driverpath
, major
, minor
));
1150 DEBUG(10,("get_correct_cversion: Driver file [%s] cversion = %d\n",
1151 driverpath
, cversion
));
1153 close_file(fsp
, True
);
1154 close_cnum(conn
, user
->vuid
);
1163 close_file(fsp
, True
);
1165 close_cnum(conn
, user
->vuid
);
1170 /****************************************************************************
1171 ****************************************************************************/
1172 static WERROR
clean_up_driver_struct_level_3(NT_PRINTER_DRIVER_INFO_LEVEL_3
*driver
,
1173 struct current_user
*user
)
1175 fstring architecture
;
1181 /* clean up the driver name.
1182 * we can get .\driver.dll
1183 * or worse c:\windows\system\driver.dll !
1185 /* using an intermediate string to not have overlaping memcpy()'s */
1186 if ((p
= strrchr(driver
->driverpath
,'\\')) != NULL
) {
1187 fstrcpy(new_name
, p
+1);
1188 fstrcpy(driver
->driverpath
, new_name
);
1191 if ((p
= strrchr(driver
->datafile
,'\\')) != NULL
) {
1192 fstrcpy(new_name
, p
+1);
1193 fstrcpy(driver
->datafile
, new_name
);
1196 if ((p
= strrchr(driver
->configfile
,'\\')) != NULL
) {
1197 fstrcpy(new_name
, p
+1);
1198 fstrcpy(driver
->configfile
, new_name
);
1201 if ((p
= strrchr(driver
->helpfile
,'\\')) != NULL
) {
1202 fstrcpy(new_name
, p
+1);
1203 fstrcpy(driver
->helpfile
, new_name
);
1206 if (driver
->dependentfiles
) {
1207 for (i
=0; *driver
->dependentfiles
[i
]; i
++) {
1208 if ((p
= strrchr(driver
->dependentfiles
[i
],'\\')) != NULL
) {
1209 fstrcpy(new_name
, p
+1);
1210 fstrcpy(driver
->dependentfiles
[i
], new_name
);
1215 get_short_archi(architecture
, driver
->environment
);
1217 /* jfm:7/16/2000 the client always sends the cversion=0.
1218 * The server should check which version the driver is by reading
1219 * the PE header of driver->driverpath.
1221 * For Windows 95/98 the version is 0 (so the value sent is correct)
1222 * For Windows NT (the architecture doesn't matter)
1223 * NT 3.1: cversion=0
1224 * NT 3.5/3.51: cversion=1
1228 if ((driver
->cversion
= get_correct_cversion( architecture
,
1229 driver
->driverpath
, user
, &err
)) == -1)
1235 /****************************************************************************
1236 ****************************************************************************/
1237 static WERROR
clean_up_driver_struct_level_6(NT_PRINTER_DRIVER_INFO_LEVEL_6
*driver
,
1238 struct current_user
*user
)
1240 fstring architecture
;
1246 /* clean up the driver name.
1247 * we can get .\driver.dll
1248 * or worse c:\windows\system\driver.dll !
1250 /* using an intermediate string to not have overlaping memcpy()'s */
1251 if ((p
= strrchr(driver
->driverpath
,'\\')) != NULL
) {
1252 fstrcpy(new_name
, p
+1);
1253 fstrcpy(driver
->driverpath
, new_name
);
1256 if ((p
= strrchr(driver
->datafile
,'\\')) != NULL
) {
1257 fstrcpy(new_name
, p
+1);
1258 fstrcpy(driver
->datafile
, new_name
);
1261 if ((p
= strrchr(driver
->configfile
,'\\')) != NULL
) {
1262 fstrcpy(new_name
, p
+1);
1263 fstrcpy(driver
->configfile
, new_name
);
1266 if ((p
= strrchr(driver
->helpfile
,'\\')) != NULL
) {
1267 fstrcpy(new_name
, p
+1);
1268 fstrcpy(driver
->helpfile
, new_name
);
1271 if (driver
->dependentfiles
) {
1272 for (i
=0; *driver
->dependentfiles
[i
]; i
++) {
1273 if ((p
= strrchr(driver
->dependentfiles
[i
],'\\')) != NULL
) {
1274 fstrcpy(new_name
, p
+1);
1275 fstrcpy(driver
->dependentfiles
[i
], new_name
);
1280 get_short_archi(architecture
, driver
->environment
);
1282 /* jfm:7/16/2000 the client always sends the cversion=0.
1283 * The server should check which version the driver is by reading
1284 * the PE header of driver->driverpath.
1286 * For Windows 95/98 the version is 0 (so the value sent is correct)
1287 * For Windows NT (the architecture doesn't matter)
1288 * NT 3.1: cversion=0
1289 * NT 3.5/3.51: cversion=1
1293 if ((driver
->version
= get_correct_cversion(architecture
,
1294 driver
->driverpath
, user
, &err
)) == -1)
1300 /****************************************************************************
1301 ****************************************************************************/
1302 WERROR
clean_up_driver_struct(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract
,
1303 uint32 level
, struct current_user
*user
)
1308 NT_PRINTER_DRIVER_INFO_LEVEL_3
*driver
;
1309 driver
=driver_abstract
.info_3
;
1310 return clean_up_driver_struct_level_3(driver
, user
);
1314 NT_PRINTER_DRIVER_INFO_LEVEL_6
*driver
;
1315 driver
=driver_abstract
.info_6
;
1316 return clean_up_driver_struct_level_6(driver
, user
);
1319 return WERR_INVALID_PARAM
;
1323 /****************************************************************************
1324 This function sucks and should be replaced. JRA.
1325 ****************************************************************************/
1327 static void convert_level_6_to_level3(NT_PRINTER_DRIVER_INFO_LEVEL_3
*dst
, NT_PRINTER_DRIVER_INFO_LEVEL_6
*src
)
1329 dst
->cversion
= src
->version
;
1331 fstrcpy( dst
->name
, src
->name
);
1332 fstrcpy( dst
->environment
, src
->environment
);
1333 fstrcpy( dst
->driverpath
, src
->driverpath
);
1334 fstrcpy( dst
->datafile
, src
->datafile
);
1335 fstrcpy( dst
->configfile
, src
->configfile
);
1336 fstrcpy( dst
->helpfile
, src
->helpfile
);
1337 fstrcpy( dst
->monitorname
, src
->monitorname
);
1338 fstrcpy( dst
->defaultdatatype
, src
->defaultdatatype
);
1339 dst
->dependentfiles
= src
->dependentfiles
;
1342 #if 0 /* Debugging function */
1344 static char* ffmt(unsigned char *c
){
1346 static char ffmt_str
[17];
1348 for (i
=0; i
<16; i
++) {
1349 if ((c
[i
] < ' ') || (c
[i
] > '~'))
1360 /****************************************************************************
1361 ****************************************************************************/
1362 BOOL
move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract
, uint32 level
,
1363 struct current_user
*user
, WERROR
*perr
)
1365 NT_PRINTER_DRIVER_INFO_LEVEL_3
*driver
;
1366 NT_PRINTER_DRIVER_INFO_LEVEL_3 converted_driver
;
1367 fstring architecture
;
1373 connection_struct
*conn
;
1376 struct passwd
*pass
;
1381 memset(inbuf
, '\0', sizeof(inbuf
));
1382 memset(outbuf
, '\0', sizeof(outbuf
));
1386 driver
=driver_abstract
.info_3
;
1387 else if (level
==6) {
1388 convert_level_6_to_level3(&converted_driver
, driver_abstract
.info_6
);
1389 driver
= &converted_driver
;
1391 DEBUG(0,("move_driver_to_download_area: Unknown info level (%u)\n", (unsigned int)level
));
1395 get_short_archi(architecture
, driver
->environment
);
1398 pass
= sys_getpwuid(user
->uid
);
1400 DEBUG(0,("move_driver_to_download_area: Unable to get passwd entry for uid %u\n",
1401 (unsigned int)user
->uid
));
1407 * Connect to the print$ share under the same account as the user connected to the rpc pipe.
1408 * Note we must be root to do this.
1411 fstrcpy(user_name
, pass
->pw_name
);
1412 DEBUG(10,("move_driver_to_download_area: uid %d -> user %s\n", (int)user
->uid
, user_name
));
1414 /* Null password is ok - we are already an authenticated user... */
1416 conn
= make_connection("print$", user_name
, null_pw
, 0, "A:", user
->vuid
, &ecode
);
1420 DEBUG(0,("move_driver_to_download_area: Unable to connect\n"));
1421 *perr
= W_ERROR(ecode
);
1426 * Save who we are - we are temporarily becoming the connection user.
1429 if (!become_user(conn
, conn
->vuid
)) {
1430 DEBUG(0,("move_driver_to_download_area: Can't become user %s\n", user_name
));
1435 * make the directories version and version\driver_name
1436 * under the architecture directory.
1438 DEBUG(5,("Creating first directory\n"));
1439 slprintf(new_dir
, sizeof(new_dir
)-1, "%s/%d", architecture
, driver
->cversion
);
1440 mkdir_internal(conn
, new_dir
);
1442 /* For each driver file, archi\filexxx.yyy, if there is a duplicate file
1443 * listed for this driver which has already been moved, skip it (note:
1444 * drivers may list the same file name several times. Then check if the
1445 * file already exists in archi\cversion\, if so, check that the version
1446 * info (or time stamps if version info is unavailable) is newer (or the
1447 * date is later). If it is, move it to archi\cversion\filexxx.yyy.
1448 * Otherwise, delete the file.
1450 * If a file is not moved to archi\cversion\ because of an error, all the
1451 * rest of the 'unmoved' driver files are removed from archi\. If one or
1452 * more of the driver's files was already moved to archi\cversion\, it
1453 * potentially leaves the driver in a partially updated state. Version
1454 * trauma will most likely occur if an client attempts to use any printer
1455 * bound to the driver. Perhaps a rewrite to make sure the moves can be
1456 * done is appropriate... later JRR
1459 DEBUG(5,("Moving files now !\n"));
1461 if (driver
->driverpath
&& strlen(driver
->driverpath
)) {
1462 slprintf(new_name
, sizeof(new_name
)-1, "%s/%s", architecture
, driver
->driverpath
);
1463 slprintf(old_name
, sizeof(old_name
)-1, "%s/%s", new_dir
, driver
->driverpath
);
1464 if (ver
!= -1 && (ver
=file_version_is_newer(conn
, new_name
, old_name
)) > 0) {
1466 status
= rename_internals(conn
, new_name
, old_name
, True
);
1467 if (!NT_STATUS_IS_OK(status
)) {
1468 DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
1469 new_name
, old_name
));
1470 *perr
= ntstatus_to_werror(status
);
1471 unlink_internals(conn
, 0, new_name
);
1476 unlink_internals(conn
, 0, new_name
);
1479 if (driver
->datafile
&& strlen(driver
->datafile
)) {
1480 if (!strequal(driver
->datafile
, driver
->driverpath
)) {
1481 slprintf(new_name
, sizeof(new_name
)-1, "%s/%s", architecture
, driver
->datafile
);
1482 slprintf(old_name
, sizeof(old_name
)-1, "%s/%s", new_dir
, driver
->datafile
);
1483 if (ver
!= -1 && (ver
=file_version_is_newer(conn
, new_name
, old_name
)) > 0) {
1485 status
= rename_internals(conn
, new_name
, old_name
, True
);
1486 if (!NT_STATUS_IS_OK(status
)) {
1487 DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
1488 new_name
, old_name
));
1489 *perr
= ntstatus_to_werror(status
);
1490 unlink_internals(conn
, 0, new_name
);
1495 unlink_internals(conn
, 0, new_name
);
1499 if (driver
->configfile
&& strlen(driver
->configfile
)) {
1500 if (!strequal(driver
->configfile
, driver
->driverpath
) &&
1501 !strequal(driver
->configfile
, driver
->datafile
)) {
1502 slprintf(new_name
, sizeof(new_name
)-1, "%s/%s", architecture
, driver
->configfile
);
1503 slprintf(old_name
, sizeof(old_name
)-1, "%s/%s", new_dir
, driver
->configfile
);
1504 if (ver
!= -1 && (ver
=file_version_is_newer(conn
, new_name
, old_name
)) > 0) {
1506 status
= rename_internals(conn
, new_name
, old_name
, True
);
1507 if (!NT_STATUS_IS_OK(status
)) {
1508 DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
1509 new_name
, old_name
));
1510 *perr
= ntstatus_to_werror(status
);
1511 unlink_internals(conn
, 0, new_name
);
1516 unlink_internals(conn
, 0, new_name
);
1520 if (driver
->helpfile
&& strlen(driver
->helpfile
)) {
1521 if (!strequal(driver
->helpfile
, driver
->driverpath
) &&
1522 !strequal(driver
->helpfile
, driver
->datafile
) &&
1523 !strequal(driver
->helpfile
, driver
->configfile
)) {
1524 slprintf(new_name
, sizeof(new_name
)-1, "%s/%s", architecture
, driver
->helpfile
);
1525 slprintf(old_name
, sizeof(old_name
)-1, "%s/%s", new_dir
, driver
->helpfile
);
1526 if (ver
!= -1 && (ver
=file_version_is_newer(conn
, new_name
, old_name
)) > 0) {
1528 status
= rename_internals(conn
, new_name
, old_name
, True
);
1529 if (!NT_STATUS_IS_OK(status
)) {
1530 DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
1531 new_name
, old_name
));
1532 *perr
= ntstatus_to_werror(status
);
1533 unlink_internals(conn
, 0, new_name
);
1538 unlink_internals(conn
, 0, new_name
);
1542 if (driver
->dependentfiles
) {
1543 for (i
=0; *driver
->dependentfiles
[i
]; i
++) {
1544 if (!strequal(driver
->dependentfiles
[i
], driver
->driverpath
) &&
1545 !strequal(driver
->dependentfiles
[i
], driver
->datafile
) &&
1546 !strequal(driver
->dependentfiles
[i
], driver
->configfile
) &&
1547 !strequal(driver
->dependentfiles
[i
], driver
->helpfile
)) {
1549 for (j
=0; j
< i
; j
++) {
1550 if (strequal(driver
->dependentfiles
[i
], driver
->dependentfiles
[j
])) {
1555 slprintf(new_name
, sizeof(new_name
)-1, "%s/%s", architecture
, driver
->dependentfiles
[i
]);
1556 slprintf(old_name
, sizeof(old_name
)-1, "%s/%s", new_dir
, driver
->dependentfiles
[i
]);
1557 if (ver
!= -1 && (ver
=file_version_is_newer(conn
, new_name
, old_name
)) > 0) {
1559 status
= rename_internals(conn
, new_name
, old_name
, True
);
1560 if (!NT_STATUS_IS_OK(status
)) {
1561 DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
1562 new_name
, old_name
));
1563 *perr
= ntstatus_to_werror(status
);
1564 unlink_internals(conn
, 0, new_name
);
1569 unlink_internals(conn
, 0, new_name
);
1575 close_cnum(conn
, user
->vuid
);
1578 return ver
== -1 ? False
: True
;
1581 /****************************************************************************
1582 ****************************************************************************/
1583 static uint32
add_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3
*driver
)
1586 fstring architecture
;
1592 TDB_DATA kbuf
, dbuf
;
1594 get_short_archi(architecture
, driver
->environment
);
1596 /* The names are relative. We store them in the form: \print$\arch\version\driver.xxx
1597 * \\server is added in the rpc server layer.
1598 * It does make sense to NOT store the server's name in the printer TDB.
1601 slprintf(directory
, sizeof(directory
)-1, "\\print$\\%s\\%d\\", architecture
, driver
->cversion
);
1603 /* .inf files do not always list a file for each of the four standard files.
1604 * Don't prepend a path to a null filename, or client claims:
1605 * "The server on which the printer resides does not have a suitable
1606 * <printer driver name> printer driver installed. Click OK if you
1607 * wish to install the driver on your local machine."
1609 if (strlen(driver
->driverpath
)) {
1610 fstrcpy(temp_name
, driver
->driverpath
);
1611 slprintf(driver
->driverpath
, sizeof(driver
->driverpath
)-1, "%s%s", directory
, temp_name
);
1614 if (strlen(driver
->datafile
)) {
1615 fstrcpy(temp_name
, driver
->datafile
);
1616 slprintf(driver
->datafile
, sizeof(driver
->datafile
)-1, "%s%s", directory
, temp_name
);
1619 if (strlen(driver
->configfile
)) {
1620 fstrcpy(temp_name
, driver
->configfile
);
1621 slprintf(driver
->configfile
, sizeof(driver
->configfile
)-1, "%s%s", directory
, temp_name
);
1624 if (strlen(driver
->helpfile
)) {
1625 fstrcpy(temp_name
, driver
->helpfile
);
1626 slprintf(driver
->helpfile
, sizeof(driver
->helpfile
)-1, "%s%s", directory
, temp_name
);
1629 if (driver
->dependentfiles
) {
1630 for (i
=0; *driver
->dependentfiles
[i
]; i
++) {
1631 fstrcpy(temp_name
, driver
->dependentfiles
[i
]);
1632 slprintf(driver
->dependentfiles
[i
], sizeof(driver
->dependentfiles
[i
])-1, "%s%s", directory
, temp_name
);
1636 slprintf(key
, sizeof(key
)-1, "%s%s/%d/%s", DRIVERS_PREFIX
, architecture
, driver
->cversion
, driver
->name
);
1637 dos_to_unix(key
); /* Convert key to unix-codepage */
1639 DEBUG(5,("add_a_printer_driver_3: Adding driver with key %s\n", key
));
1646 len
+= tdb_pack(buf
+len
, buflen
-len
, "dffffffff",
1649 driver
->environment
,
1654 driver
->monitorname
,
1655 driver
->defaultdatatype
);
1657 if (driver
->dependentfiles
) {
1658 for (i
=0; *driver
->dependentfiles
[i
]; i
++) {
1659 len
+= tdb_pack(buf
+len
, buflen
-len
, "f",
1660 driver
->dependentfiles
[i
]);
1664 if (len
!= buflen
) {
1667 tb
= (char *)Realloc(buf
, len
);
1669 DEBUG(0,("add_a_printer_driver_3: failed to enlarge buffer\n!"));
1680 kbuf
.dsize
= strlen(key
)+1;
1684 ret
= tdb_store(tdb_drivers
, kbuf
, dbuf
, TDB_REPLACE
);
1688 DEBUG(0,("add_a_printer_driver_3: Adding driver with key %s failed.\n", key
));
1694 /****************************************************************************
1695 ****************************************************************************/
1696 static uint32
add_a_printer_driver_6(NT_PRINTER_DRIVER_INFO_LEVEL_6
*driver
)
1698 NT_PRINTER_DRIVER_INFO_LEVEL_3 info3
;
1701 info3
.cversion
= driver
->version
;
1702 fstrcpy(info3
.name
,driver
->name
);
1703 fstrcpy(info3
.environment
,driver
->environment
);
1704 fstrcpy(info3
.driverpath
,driver
->driverpath
);
1705 fstrcpy(info3
.datafile
,driver
->datafile
);
1706 fstrcpy(info3
.configfile
,driver
->configfile
);
1707 fstrcpy(info3
.helpfile
,driver
->helpfile
);
1708 fstrcpy(info3
.monitorname
,driver
->monitorname
);
1709 fstrcpy(info3
.defaultdatatype
,driver
->defaultdatatype
);
1710 info3
.dependentfiles
= driver
->dependentfiles
;
1712 return add_a_printer_driver_3(&info3
);
1716 /****************************************************************************
1717 ****************************************************************************/
1718 static WERROR
get_a_printer_driver_3_default(NT_PRINTER_DRIVER_INFO_LEVEL_3
**info_ptr
, fstring in_prt
, fstring in_arch
)
1720 NT_PRINTER_DRIVER_INFO_LEVEL_3 info
;
1724 fstrcpy(info
.name
, in_prt
);
1725 fstrcpy(info
.defaultdatatype
, "RAW");
1727 fstrcpy(info
.driverpath
, "");
1728 fstrcpy(info
.datafile
, "");
1729 fstrcpy(info
.configfile
, "");
1730 fstrcpy(info
.helpfile
, "");
1732 if ((info
.dependentfiles
=(fstring
*)malloc(2*sizeof(fstring
))) == NULL
)
1735 memset(info
.dependentfiles
, '\0', 2*sizeof(fstring
));
1736 fstrcpy(info
.dependentfiles
[0], "");
1738 *info_ptr
= memdup(&info
, sizeof(info
));
1743 /****************************************************************************
1744 ****************************************************************************/
1745 static WERROR
get_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3
**info_ptr
, fstring in_prt
, fstring in_arch
, uint32 version
)
1747 NT_PRINTER_DRIVER_INFO_LEVEL_3 driver
;
1748 TDB_DATA kbuf
, dbuf
;
1749 fstring architecture
;
1754 ZERO_STRUCT(driver
);
1756 get_short_archi(architecture
, in_arch
);
1758 DEBUG(8,("get_a_printer_driver_3: [%s%s/%d/%s]\n", DRIVERS_PREFIX
, architecture
, version
, in_prt
));
1760 slprintf(key
, sizeof(key
)-1, "%s%s/%d/%s", DRIVERS_PREFIX
, architecture
, version
, in_prt
);
1763 kbuf
.dsize
= strlen(key
)+1;
1765 dbuf
= tdb_fetch(tdb_drivers
, kbuf
);
1767 if (!dbuf
.dptr
) return get_a_printer_driver_3_default(info_ptr
, in_prt
, in_arch
);
1769 if (!dbuf
.dptr
) return WERR_ACCESS_DENIED
;
1771 len
+= tdb_unpack(dbuf
.dptr
, dbuf
.dsize
, "dffffffff",
1780 driver
.defaultdatatype
);
1783 while (len
< dbuf
.dsize
) {
1786 tddfs
= (fstring
*)Realloc(driver
.dependentfiles
,
1787 sizeof(fstring
)*(i
+2));
1788 if (tddfs
== NULL
) {
1789 DEBUG(0,("get_a_printer_driver_3: failed to enlarge buffer!\n"));
1792 else driver
.dependentfiles
= tddfs
;
1794 len
+= tdb_unpack(dbuf
.dptr
+len
, dbuf
.dsize
-len
, "f",
1795 &driver
.dependentfiles
[i
]);
1798 if (driver
.dependentfiles
!= NULL
)
1799 fstrcpy(driver
.dependentfiles
[i
], "");
1801 SAFE_FREE(dbuf
.dptr
);
1803 if (len
!= dbuf
.dsize
) {
1804 SAFE_FREE(driver
.dependentfiles
);
1806 return get_a_printer_driver_3_default(info_ptr
, in_prt
, in_arch
);
1809 *info_ptr
= (NT_PRINTER_DRIVER_INFO_LEVEL_3
*)memdup(&driver
, sizeof(driver
));
1814 /****************************************************************************
1815 ****************************************************************************/
1816 uint32
get_a_printer_driver_9x_compatible(pstring line
, fstring model
)
1818 NT_PRINTER_DRIVER_INFO_LEVEL_3
*info3
;
1824 slprintf(key
, sizeof(key
)-1, "%s%s/%d/%s", DRIVERS_PREFIX
, "WIN40", 0, model
);
1825 DEBUG(10,("driver key: [%s]\n", key
));
1828 kbuf
.dsize
= strlen(key
)+1;
1829 if (!tdb_exists(tdb_drivers
, kbuf
))
1833 get_a_printer_driver_3(&info3
, model
, "Windows 4.0", 0);
1835 DEBUGADD(10,("info3->name [%s]\n", info3
->name
));
1836 DEBUGADD(10,("info3->datafile [%s]\n", info3
->datafile
));
1837 DEBUGADD(10,("info3->helpfile [%s]\n", info3
->helpfile
));
1838 DEBUGADD(10,("info3->monitorname [%s]\n", info3
->monitorname
));
1839 DEBUGADD(10,("info3->defaultdatatype [%s]\n", info3
->defaultdatatype
));
1840 for (i
=0; info3
->dependentfiles
&& *info3
->dependentfiles
[i
]; i
++) {
1841 DEBUGADD(10,("info3->dependentfiles [%s]\n", info3
->dependentfiles
[i
]));
1843 DEBUGADD(10,("info3->environment [%s]\n", info3
->environment
));
1844 DEBUGADD(10,("info3->driverpath [%s]\n", info3
->driverpath
));
1845 DEBUGADD(10,("info3->configfile [%s]\n", info3
->configfile
));
1847 /*pstrcat(line, info3->name); pstrcat(line, ":");*/
1848 trim_string(info3
->driverpath
, "\\print$\\WIN40\\0\\", 0);
1849 pstrcat(line
, info3
->driverpath
);
1851 trim_string(info3
->datafile
, "\\print$\\WIN40\\0\\", 0);
1852 pstrcat(line
, info3
->datafile
);
1854 trim_string(info3
->helpfile
, "\\print$\\WIN40\\0\\", 0);
1855 pstrcat(line
, info3
->helpfile
);
1857 trim_string(info3
->monitorname
, "\\print$\\WIN40\\0\\", 0);
1858 pstrcat(line
, info3
->monitorname
);
1860 pstrcat(line
, "RAW"); /*info3->defaultdatatype);*/
1863 for (i
=0; info3
->dependentfiles
&& *info3
->dependentfiles
[i
]; i
++) {
1865 pstrcat(line
, ","); /* don't end in a "," */
1866 trim_string(info3
->dependentfiles
[i
], "\\print$\\WIN40\\0\\", 0);
1867 pstrcat(line
, info3
->dependentfiles
[i
]);
1875 /****************************************************************************
1876 Debugging function, dump at level 6 the struct in the logs.
1877 ****************************************************************************/
1879 static uint32
dump_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver
, uint32 level
)
1882 NT_PRINTER_DRIVER_INFO_LEVEL_3
*info3
;
1885 DEBUG(106,("Dumping printer driver at level [%d]\n", level
));
1891 if (driver
.info_3
== NULL
)
1894 info3
=driver
.info_3
;
1896 DEBUGADD(106,("version:[%d]\n", info3
->cversion
));
1897 DEBUGADD(106,("name:[%s]\n", info3
->name
));
1898 DEBUGADD(106,("environment:[%s]\n", info3
->environment
));
1899 DEBUGADD(106,("driverpath:[%s]\n", info3
->driverpath
));
1900 DEBUGADD(106,("datafile:[%s]\n", info3
->datafile
));
1901 DEBUGADD(106,("configfile:[%s]\n", info3
->configfile
));
1902 DEBUGADD(106,("helpfile:[%s]\n", info3
->helpfile
));
1903 DEBUGADD(106,("monitorname:[%s]\n", info3
->monitorname
));
1904 DEBUGADD(106,("defaultdatatype:[%s]\n", info3
->defaultdatatype
));
1906 for (i
=0; info3
->dependentfiles
&&
1907 *info3
->dependentfiles
[i
]; i
++) {
1908 DEBUGADD(106,("dependentfile:[%s]\n",
1909 info3
->dependentfiles
[i
]));
1916 DEBUGADD(106,("dump_a_printer_driver: Level %u not implemented\n", (unsigned int)level
));
1924 /****************************************************************************
1925 ****************************************************************************/
1926 static int pack_devicemode(NT_DEVICEMODE
*nt_devmode
, char *buf
, int buflen
)
1930 len
+= tdb_pack(buf
+len
, buflen
-len
, "p", nt_devmode
);
1932 if (!nt_devmode
) return len
;
1934 len
+= tdb_pack(buf
+len
, buflen
-len
, "ffwwwwwwwwwwwwwwwwwwddddddddddddddp",
1935 nt_devmode
->devicename
,
1936 nt_devmode
->formname
,
1938 nt_devmode
->specversion
,
1939 nt_devmode
->driverversion
,
1941 nt_devmode
->driverextra
,
1942 nt_devmode
->orientation
,
1943 nt_devmode
->papersize
,
1944 nt_devmode
->paperlength
,
1945 nt_devmode
->paperwidth
,
1948 nt_devmode
->defaultsource
,
1949 nt_devmode
->printquality
,
1952 nt_devmode
->yresolution
,
1953 nt_devmode
->ttoption
,
1954 nt_devmode
->collate
,
1955 nt_devmode
->logpixels
,
1958 nt_devmode
->bitsperpel
,
1959 nt_devmode
->pelswidth
,
1960 nt_devmode
->pelsheight
,
1961 nt_devmode
->displayflags
,
1962 nt_devmode
->displayfrequency
,
1963 nt_devmode
->icmmethod
,
1964 nt_devmode
->icmintent
,
1965 nt_devmode
->mediatype
,
1966 nt_devmode
->dithertype
,
1967 nt_devmode
->reserved1
,
1968 nt_devmode
->reserved2
,
1969 nt_devmode
->panningwidth
,
1970 nt_devmode
->panningheight
,
1971 nt_devmode
->private);
1974 if (nt_devmode
->private) {
1975 len
+= tdb_pack(buf
+len
, buflen
-len
, "B",
1976 nt_devmode
->driverextra
,
1977 nt_devmode
->private);
1980 DEBUG(8,("Packed devicemode [%s]\n", nt_devmode
->formname
));
1985 /****************************************************************************
1986 ****************************************************************************/
1987 static int pack_specifics(NT_PRINTER_PARAM
*param
, char *buf
, int buflen
)
1991 while (param
!= NULL
) {
1992 len
+= tdb_pack(buf
+len
, buflen
-len
, "pfdB",
2001 len
+= tdb_pack(buf
+len
, buflen
-len
, "p", param
);
2007 /****************************************************************************
2008 Delete a printer - this just deletes the printer info file, any open
2009 handles are not affected.
2010 ****************************************************************************/
2012 uint32
del_a_printer(char *sharename
)
2017 slprintf(key
, sizeof(key
)-1, "%s%s", PRINTERS_PREFIX
, sharename
);
2018 dos_to_unix(key
); /* Convert key to unix-codepage */
2021 kbuf
.dsize
=strlen(key
)+1;
2023 tdb_delete(tdb_printers
, kbuf
);
2027 /* FIXME!!! Reorder so this forward declaration is not necessary --jerry */
2028 static WERROR
get_a_printer_2(NT_PRINTER_INFO_LEVEL_2
**, fstring
);
2029 static void free_nt_printer_info_level_2(NT_PRINTER_INFO_LEVEL_2
**);
2030 /****************************************************************************
2031 ****************************************************************************/
2032 static WERROR
update_a_printer_2(NT_PRINTER_INFO_LEVEL_2
*info
)
2038 TDB_DATA kbuf
, dbuf
;
2041 * in addprinter: no servername and the printer is the name
2042 * in setprinter: servername is \\server
2043 * and printer is \\server\\printer
2045 * Samba manages only local printers.
2046 * we currently don't support things like path=\\other_server\printer
2049 if (info
->servername
[0]!='\0') {
2050 trim_string(info
->printername
, info
->servername
, NULL
);
2051 trim_string(info
->printername
, "\\", NULL
);
2052 info
->servername
[0]='\0';
2056 * JFM: one day I'll forget.
2057 * below that's info->portname because that's the SAMBA sharename
2058 * and I made NT 'thinks' it's the portname
2059 * the info->sharename is the thing you can name when you add a printer
2060 * that's the short-name when you create shared printer for 95/98
2061 * So I've made a limitation in SAMBA: you can only have 1 printer model
2062 * behind a SAMBA share.
2070 len
+= tdb_pack(buf
+len
, buflen
-len
, "dddddddddddfffffPfffff",
2073 info
->default_priority
,
2090 info
->printprocessor
,
2094 len
+= pack_devicemode(info
->devmode
, buf
+len
, buflen
-len
);
2096 len
+= pack_specifics(info
->specific
, buf
+len
, buflen
-len
);
2098 if (buflen
!= len
) {
2101 tb
= (char *)Realloc(buf
, len
);
2103 DEBUG(0,("update_a_printer_2: failed to enlarge buffer!\n"));
2113 slprintf(key
, sizeof(key
)-1, "%s%s", PRINTERS_PREFIX
, info
->sharename
);
2114 dos_to_unix(key
); /* Convert key to unix-codepage */
2117 kbuf
.dsize
= strlen(key
)+1;
2121 ret
= (tdb_store(tdb_printers
, kbuf
, dbuf
, TDB_REPLACE
) == 0? WERR_OK
: WERR_NOMEM
);
2124 if (!W_ERROR_IS_OK(ret
))
2125 DEBUG(8, ("error updating printer to tdb on disk\n"));
2129 DEBUG(8,("packed printer [%s] with driver [%s] portname=[%s] len=%d\n",
2130 info
->sharename
, info
->drivername
, info
->portname
, len
));
2136 /****************************************************************************
2137 ****************************************************************************/
2138 void add_a_specific_param(NT_PRINTER_INFO_LEVEL_2
*info_2
, NT_PRINTER_PARAM
**param
)
2140 NT_PRINTER_PARAM
*current
;
2142 DEBUG(108,("add_a_specific_param\n"));
2144 (*param
)->next
=NULL
;
2146 if (info_2
->specific
== NULL
)
2148 info_2
->specific
=*param
;
2152 current
=info_2
->specific
;
2153 while (current
->next
!= NULL
) {
2154 current
=current
->next
;
2156 current
->next
=*param
;
2162 /****************************************************************************
2163 ****************************************************************************/
2164 BOOL
unlink_specific_param_if_exist(NT_PRINTER_INFO_LEVEL_2
*info_2
, NT_PRINTER_PARAM
*param
)
2166 NT_PRINTER_PARAM
*current
;
2167 NT_PRINTER_PARAM
*previous
;
2169 current
=info_2
->specific
;
2172 if (current
==NULL
) return (False
);
2174 if ( !strcmp(current
->value
, param
->value
) &&
2175 (strlen(current
->value
)==strlen(param
->value
)) ) {
2176 DEBUG(109,("deleting first value\n"));
2177 info_2
->specific
=current
->next
;
2178 SAFE_FREE(current
->data
);
2180 DEBUG(109,("deleted first value\n"));
2184 current
=previous
->next
;
2186 while ( current
!=NULL
) {
2187 if (!strcmp(current
->value
, param
->value
) &&
2188 strlen(current
->value
)==strlen(param
->value
) ) {
2189 DEBUG(109,("deleting current value\n"));
2190 previous
->next
=current
->next
;
2191 SAFE_FREE(current
->data
);
2193 DEBUG(109,("deleted current value\n"));
2197 previous
=previous
->next
;
2198 current
=current
->next
;
2203 /****************************************************************************
2204 Clean up and deallocate a (maybe partially) allocated NT_PRINTER_PARAM.
2205 ****************************************************************************/
2206 void free_nt_printer_param(NT_PRINTER_PARAM
**param_ptr
)
2208 NT_PRINTER_PARAM
*param
= *param_ptr
;
2213 DEBUG(106,("free_nt_printer_param: deleting param [%s]\n", param
->value
));
2215 SAFE_FREE(param
->data
);
2216 SAFE_FREE(*param_ptr
);
2219 /****************************************************************************
2220 Malloc and return an NT devicemode.
2221 ****************************************************************************/
2223 NT_DEVICEMODE
*construct_nt_devicemode(const fstring default_devicename
)
2227 NT_DEVICEMODE
*nt_devmode
= (NT_DEVICEMODE
*)malloc(sizeof(NT_DEVICEMODE
));
2229 if (nt_devmode
== NULL
) {
2230 DEBUG(0,("construct_nt_devicemode: malloc fail.\n"));
2234 ZERO_STRUCTP(nt_devmode
);
2236 safe_strcpy(adevice
, default_devicename
, sizeof(adevice
));
2237 fstrcpy(nt_devmode
->devicename
, adevice
);
2239 fstrcpy(nt_devmode
->formname
, "Letter");
2241 nt_devmode
->specversion
= 0x0401;
2242 nt_devmode
->driverversion
= 0x0400;
2243 nt_devmode
->size
= 0x00DC;
2244 nt_devmode
->driverextra
= 0x0000;
2245 nt_devmode
->fields
= FORMNAME
| TTOPTION
| PRINTQUALITY
|
2246 DEFAULTSOURCE
| COPIES
| SCALE
|
2247 PAPERSIZE
| ORIENTATION
;
2248 nt_devmode
->orientation
= 1;
2249 nt_devmode
->papersize
= PAPER_LETTER
;
2250 nt_devmode
->paperlength
= 0;
2251 nt_devmode
->paperwidth
= 0;
2252 nt_devmode
->scale
= 0x64;
2253 nt_devmode
->copies
= 1;
2254 nt_devmode
->defaultsource
= BIN_FORMSOURCE
;
2255 nt_devmode
->printquality
= RES_HIGH
; /* 0x0258 */
2256 nt_devmode
->color
= COLOR_MONOCHROME
;
2257 nt_devmode
->duplex
= DUP_SIMPLEX
;
2258 nt_devmode
->yresolution
= 0;
2259 nt_devmode
->ttoption
= TT_SUBDEV
;
2260 nt_devmode
->collate
= COLLATE_FALSE
;
2261 nt_devmode
->icmmethod
= 0;
2262 nt_devmode
->icmintent
= 0;
2263 nt_devmode
->mediatype
= 0;
2264 nt_devmode
->dithertype
= 0;
2266 /* non utilisés par un driver d'imprimante */
2267 nt_devmode
->logpixels
= 0;
2268 nt_devmode
->bitsperpel
= 0;
2269 nt_devmode
->pelswidth
= 0;
2270 nt_devmode
->pelsheight
= 0;
2271 nt_devmode
->displayflags
= 0;
2272 nt_devmode
->displayfrequency
= 0;
2273 nt_devmode
->reserved1
= 0;
2274 nt_devmode
->reserved2
= 0;
2275 nt_devmode
->panningwidth
= 0;
2276 nt_devmode
->panningheight
= 0;
2278 nt_devmode
->private = NULL
;
2282 /****************************************************************************
2283 Deepcopy an NT devicemode.
2284 ****************************************************************************/
2286 NT_DEVICEMODE
*dup_nt_devicemode(NT_DEVICEMODE
*nt_devicemode
)
2288 NT_DEVICEMODE
*new_nt_devicemode
= NULL
;
2290 if ((new_nt_devicemode
= (NT_DEVICEMODE
*)memdup(nt_devicemode
, sizeof(NT_DEVICEMODE
))) == NULL
) {
2291 DEBUG(0,("dup_nt_devicemode: malloc fail.\n"));
2295 new_nt_devicemode
->private = NULL
;
2296 if (nt_devicemode
->private != NULL
) {
2297 if ((new_nt_devicemode
->private = memdup(nt_devicemode
->private, nt_devicemode
->driverextra
)) == NULL
) {
2298 SAFE_FREE(new_nt_devicemode
);
2299 DEBUG(0,("dup_nt_devicemode: malloc fail.\n"));
2304 return new_nt_devicemode
;
2307 /****************************************************************************
2308 Clean up and deallocate a (maybe partially) allocated NT_DEVICEMODE.
2309 ****************************************************************************/
2311 void free_nt_devicemode(NT_DEVICEMODE
**devmode_ptr
)
2313 NT_DEVICEMODE
*nt_devmode
= *devmode_ptr
;
2315 if(nt_devmode
== NULL
)
2318 DEBUG(106,("free_nt_devicemode: deleting DEVMODE\n"));
2320 SAFE_FREE(nt_devmode
->private);
2321 SAFE_FREE(*devmode_ptr
);
2324 /****************************************************************************
2325 Clean up and deallocate a (maybe partially) allocated NT_PRINTER_INFO_LEVEL_2.
2326 ****************************************************************************/
2327 static void free_nt_printer_info_level_2(NT_PRINTER_INFO_LEVEL_2
**info_ptr
)
2329 NT_PRINTER_INFO_LEVEL_2
*info
= *info_ptr
;
2330 NT_PRINTER_PARAM
*param_ptr
;
2335 DEBUG(106,("free_nt_printer_info_level_2: deleting info\n"));
2337 free_nt_devicemode(&info
->devmode
);
2339 for(param_ptr
= info
->specific
; param_ptr
; ) {
2340 NT_PRINTER_PARAM
*tofree
= param_ptr
;
2342 param_ptr
= param_ptr
->next
;
2343 free_nt_printer_param(&tofree
);
2346 SAFE_FREE(*info_ptr
);
2350 /****************************************************************************
2351 ****************************************************************************/
2352 static int unpack_devicemode(NT_DEVICEMODE
**nt_devmode
, char *buf
, int buflen
)
2356 NT_DEVICEMODE devmode
;
2358 ZERO_STRUCT(devmode
);
2360 len
+= tdb_unpack(buf
+len
, buflen
-len
, "p", nt_devmode
);
2362 if (!*nt_devmode
) return len
;
2364 len
+= tdb_unpack(buf
+len
, buflen
-len
, "ffwwwwwwwwwwwwwwwwwwddddddddddddddp",
2368 &devmode
.specversion
,
2369 &devmode
.driverversion
,
2371 &devmode
.driverextra
,
2372 &devmode
.orientation
,
2374 &devmode
.paperlength
,
2375 &devmode
.paperwidth
,
2378 &devmode
.defaultsource
,
2379 &devmode
.printquality
,
2382 &devmode
.yresolution
,
2388 &devmode
.bitsperpel
,
2390 &devmode
.pelsheight
,
2391 &devmode
.displayflags
,
2392 &devmode
.displayfrequency
,
2396 &devmode
.dithertype
,
2399 &devmode
.panningwidth
,
2400 &devmode
.panningheight
,
2403 if (devmode
.private) {
2404 /* the len in tdb_unpack is an int value and
2405 * devmode.driverextra is only a short
2407 len
+= tdb_unpack(buf
+len
, buflen
-len
, "B", &extra_len
, &devmode
.private);
2408 devmode
.driverextra
=(uint16
)extra_len
;
2410 /* check to catch an invalid TDB entry so we don't segfault */
2411 if (devmode
.driverextra
== 0) {
2412 devmode
.private = NULL
;
2416 *nt_devmode
= (NT_DEVICEMODE
*)memdup(&devmode
, sizeof(devmode
));
2418 DEBUG(8,("Unpacked devicemode [%s](%s)\n", devmode
.devicename
, devmode
.formname
));
2419 if (devmode
.private)
2420 DEBUG(8,("with a private section of %d bytes\n", devmode
.driverextra
));
2425 /****************************************************************************
2426 ****************************************************************************/
2427 static int unpack_specifics(NT_PRINTER_PARAM
**list
, char *buf
, int buflen
)
2430 NT_PRINTER_PARAM param
, *p
;
2435 len
+= tdb_unpack(buf
+len
, buflen
-len
, "p", &p
);
2438 len
+= tdb_unpack(buf
+len
, buflen
-len
, "fdB",
2444 *list
= memdup(¶m
, sizeof(param
));
2446 DEBUG(8,("specific: [%s], len: %d\n", param
.value
, param
.data_len
));
2452 static void map_to_os2_driver(fstring drivername
)
2454 static BOOL initialised
=False
;
2455 static fstring last_from
,last_to
;
2456 char *mapfile
= lp_os2_driver_map();
2457 char **lines
= NULL
;
2461 if (!strlen(drivername
))
2468 *last_from
= *last_to
= 0;
2472 if (strequal(drivername
,last_from
)) {
2473 DEBUG(3,("Mapped Windows driver %s to OS/2 driver %s\n",drivername
,last_to
));
2474 fstrcpy(drivername
,last_to
);
2478 lines
= file_lines_load(mapfile
, &numlines
, True
);
2479 if (numlines
== 0) {
2480 DEBUG(0,("No entries in OS/2 driver map %s\n",mapfile
));
2484 DEBUG(4,("Scanning OS/2 driver map %s\n",mapfile
));
2486 for( i
= 0; i
< numlines
; i
++) {
2487 char *nt_name
= lines
[i
];
2488 char *os2_name
= strchr(nt_name
,'=');
2495 while (isspace(*nt_name
))
2498 if (!*nt_name
|| strchr("#;",*nt_name
))
2502 int l
= strlen(nt_name
);
2503 while (l
&& isspace(nt_name
[l
-1])) {
2509 while (isspace(*os2_name
))
2513 int l
= strlen(os2_name
);
2514 while (l
&& isspace(os2_name
[l
-1])) {
2520 if (strequal(nt_name
,drivername
)) {
2521 DEBUG(3,("Mapped windows driver %s to os2 driver%s\n",drivername
,os2_name
));
2522 fstrcpy(last_from
,drivername
);
2523 fstrcpy(last_to
,os2_name
);
2524 fstrcpy(drivername
,os2_name
);
2525 file_lines_free(lines
);
2530 file_lines_free(lines
);
2533 /****************************************************************************
2534 get a default printer info 2 struct
2535 ****************************************************************************/
2536 static WERROR
get_a_printer_2_default(NT_PRINTER_INFO_LEVEL_2
**info_ptr
, fstring sharename
)
2539 NT_PRINTER_INFO_LEVEL_2 info
;
2543 snum
= lp_servicenumber(sharename
);
2545 slprintf(info
.servername
, sizeof(info
.servername
)-1, "\\\\%s", get_called_name());
2546 slprintf(info
.printername
, sizeof(info
.printername
)-1, "\\\\%s\\%s",
2547 get_called_name(), sharename
);
2548 fstrcpy(info
.sharename
, sharename
);
2549 fstrcpy(info
.portname
, SAMBA_PRINTER_PORT_NAME
);
2550 fstrcpy(info
.drivername
, lp_printerdriver(snum
));
2552 /* by setting the driver name to an empty string, a local NT admin
2553 can now run the **local** APW to install a local printer driver
2554 for a Samba shared printer in 2.2. Without this, drivers **must** be
2555 installed on the Samba server for NT clients --jerry */
2556 #if 0 /* JERRY --do not uncomment-- */
2557 if (!*info
.drivername
)
2558 fstrcpy(info
.drivername
, "NO DRIVER AVAILABLE FOR THIS PRINTER");
2562 DEBUG(10,("get_a_printer_2_default: driver name set to [%s]\n", info
.drivername
));
2564 pstrcpy(info
.comment
, "");
2565 fstrcpy(info
.printprocessor
, "winprint");
2566 fstrcpy(info
.datatype
, "RAW");
2568 info
.attributes
= PRINTER_ATTRIBUTE_SHARED
| PRINTER_ATTRIBUTE_NETWORK
; /* attributes */
2570 info
.starttime
= 0; /* Minutes since 12:00am GMT */
2571 info
.untiltime
= 0; /* Minutes since 12:00am GMT */
2573 info
.default_priority
= 1;
2574 info
.setuptime
= (uint32
)time(NULL
);
2577 * I changed this as I think it is better to have a generic
2578 * DEVMODE than to crash Win2k explorer.exe --jerry
2579 * See the HP Deskjet 990c Win2k drivers for an example.
2581 * However the default devmode appears to cause problems
2582 * with the HP CLJ 8500 PCL driver. Hence the addition of
2583 * the "default devmode" parameter --jerry 22/01/2002
2586 if (lp_default_devmode(snum
)) {
2587 if ((info
.devmode
= construct_nt_devicemode(info
.printername
)) == NULL
)
2591 info
.devmode
= NULL
;
2594 /* This will get the current RPC talloc context, but we should be
2595 passing this as a parameter... fixme... JRA ! */
2597 if (!nt_printing_getsec(get_talloc_ctx(), sharename
, &info
.secdesc_buf
))
2600 *info_ptr
= (NT_PRINTER_INFO_LEVEL_2
*)memdup(&info
, sizeof(info
));
2602 DEBUG(0,("get_a_printer_2_default: malloc fail.\n"));
2610 free_nt_devicemode(&info
.devmode
);
2611 return WERR_ACCESS_DENIED
;
2614 /****************************************************************************
2615 ****************************************************************************/
2616 static WERROR
get_a_printer_2(NT_PRINTER_INFO_LEVEL_2
**info_ptr
, fstring sharename
)
2619 NT_PRINTER_INFO_LEVEL_2 info
;
2621 TDB_DATA kbuf
, dbuf
;
2622 fstring printername
;
2626 slprintf(key
, sizeof(key
)-1, "%s%s", PRINTERS_PREFIX
, sharename
);
2627 dos_to_unix(key
); /* Convert key to unix-codepage */
2630 kbuf
.dsize
= strlen(key
)+1;
2632 dbuf
= tdb_fetch(tdb_printers
, kbuf
);
2634 return get_a_printer_2_default(info_ptr
, sharename
);
2636 len
+= tdb_unpack(dbuf
.dptr
+len
, dbuf
.dsize
-len
, "dddddddddddfffffPfffff",
2639 &info
.default_priority
,
2656 info
.printprocessor
,
2660 /* Samba has to have shared raw drivers. */
2661 info
.attributes
|= (PRINTER_ATTRIBUTE_SHARED
| PRINTER_ATTRIBUTE_NETWORK
);
2663 /* Restore the stripped strings. */
2664 slprintf(info
.servername
, sizeof(info
.servername
)-1, "\\\\%s", get_called_name());
2665 slprintf(printername
, sizeof(printername
)-1, "\\\\%s\\%s", get_called_name(),
2667 fstrcpy(info
.printername
, printername
);
2669 len
+= unpack_devicemode(&info
.devmode
,dbuf
.dptr
+len
, dbuf
.dsize
-len
);
2672 * Some client drivers freak out if there is a NULL devmode
2673 * (probably the driver is not checking before accessing
2674 * the devmode pointer) --jerry
2676 * See comments in get_a_printer_2_default()
2679 if (lp_default_devmode(lp_servicenumber(sharename
)) && !info
.devmode
)
2681 DEBUG(8,("get_a_printer_2: Constructing a default device mode for [%s]\n",
2683 info
.devmode
= construct_nt_devicemode(printername
);
2686 len
+= unpack_specifics(&info
.specific
,dbuf
.dptr
+len
, dbuf
.dsize
-len
);
2688 /* This will get the current RPC talloc context, but we should be
2689 passing this as a parameter... fixme... JRA ! */
2691 nt_printing_getsec(get_talloc_ctx(), sharename
, &info
.secdesc_buf
);
2693 /* Fix for OS/2 drivers. */
2695 if (get_remote_arch() == RA_OS2
)
2696 map_to_os2_driver(info
.drivername
);
2698 SAFE_FREE(dbuf
.dptr
);
2699 *info_ptr
=memdup(&info
, sizeof(info
));
2701 DEBUG(9,("Unpacked printer [%s] name [%s] running driver [%s]\n",
2702 sharename
, info
.printername
, info
.drivername
));
2707 /****************************************************************************
2708 debugging function, dump at level 6 the struct in the logs
2709 ****************************************************************************/
2710 static uint32
dump_a_printer(NT_PRINTER_INFO_LEVEL printer
, uint32 level
)
2713 NT_PRINTER_INFO_LEVEL_2
*info2
;
2715 DEBUG(106,("Dumping printer at level [%d]\n", level
));
2721 if (printer
.info_2
== NULL
)
2725 info2
=printer
.info_2
;
2727 DEBUGADD(106,("attributes:[%d]\n", info2
->attributes
));
2728 DEBUGADD(106,("priority:[%d]\n", info2
->priority
));
2729 DEBUGADD(106,("default_priority:[%d]\n", info2
->default_priority
));
2730 DEBUGADD(106,("starttime:[%d]\n", info2
->starttime
));
2731 DEBUGADD(106,("untiltime:[%d]\n", info2
->untiltime
));
2732 DEBUGADD(106,("status:[%d]\n", info2
->status
));
2733 DEBUGADD(106,("cjobs:[%d]\n", info2
->cjobs
));
2734 DEBUGADD(106,("averageppm:[%d]\n", info2
->averageppm
));
2735 DEBUGADD(106,("changeid:[%d]\n", info2
->changeid
));
2736 DEBUGADD(106,("c_setprinter:[%d]\n", info2
->c_setprinter
));
2737 DEBUGADD(106,("setuptime:[%d]\n", info2
->setuptime
));
2739 DEBUGADD(106,("servername:[%s]\n", info2
->servername
));
2740 DEBUGADD(106,("printername:[%s]\n", info2
->printername
));
2741 DEBUGADD(106,("sharename:[%s]\n", info2
->sharename
));
2742 DEBUGADD(106,("portname:[%s]\n", info2
->portname
));
2743 DEBUGADD(106,("drivername:[%s]\n", info2
->drivername
));
2744 DEBUGADD(106,("comment:[%s]\n", info2
->comment
));
2745 DEBUGADD(106,("location:[%s]\n", info2
->location
));
2746 DEBUGADD(106,("sepfile:[%s]\n", info2
->sepfile
));
2747 DEBUGADD(106,("printprocessor:[%s]\n", info2
->printprocessor
));
2748 DEBUGADD(106,("datatype:[%s]\n", info2
->datatype
));
2749 DEBUGADD(106,("parameters:[%s]\n", info2
->parameters
));
2755 DEBUGADD(106,("dump_a_printer: Level %u not implemented\n", (unsigned int)level
));
2763 /****************************************************************************
2764 Get the parameters we can substitute in an NT print job.
2765 ****************************************************************************/
2767 void get_printer_subst_params(int snum
, fstring
*printername
, fstring
*sharename
, fstring
*portname
)
2769 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
2771 **printername
= **sharename
= **portname
= '\0';
2773 if (!W_ERROR_IS_OK(get_a_printer(&printer
, 2, lp_servicename(snum
))))
2776 fstrcpy(*printername
, printer
->info_2
->printername
);
2777 fstrcpy(*sharename
, printer
->info_2
->sharename
);
2778 fstrcpy(*portname
, printer
->info_2
->portname
);
2780 free_a_printer(&printer
, 2);
2783 /****************************************************************************
2784 Update the changeid time.
2785 This is SO NASTY as some drivers need this to change, others need it
2786 static. This value will change every second, and I must hope that this
2787 is enough..... DON'T CHANGE THIS CODE WITHOUT A TEST MATRIX THE SIZE OF
2789 ****************************************************************************/
2791 static uint32
rev_changeid(void)
2795 get_process_uptime(&tv
);
2798 /* Return changeid as msec since spooler restart */
2799 return tv
.tv_sec
* 1000 + tv
.tv_usec
/ 1000;
2802 * This setting seems to work well but is too untested
2803 * to replace the above calculation. Left in for experiementation
2804 * of the reader --jerry (Tue Mar 12 09:15:05 CST 2002)
2806 return tv
.tv_sec
* 10 + tv
.tv_usec
/ 100000;
2811 * The function below are the high level ones.
2812 * only those ones must be called from the spoolss code.
2816 /****************************************************************************
2817 Modify a printer. This is called from SETPRINTERDATA/DELETEPRINTERDATA.
2818 ****************************************************************************/
2820 WERROR
mod_a_printer(NT_PRINTER_INFO_LEVEL printer
, uint32 level
)
2824 dump_a_printer(printer
, level
);
2831 * Update the changestamp. Emperical tests show that the
2832 * ChangeID is always updated,but c_setprinter is
2833 * global spooler variable (not per printer).
2836 /* ChangeID **must** be increasing over the lifetime
2837 of client's spoolss service in order for the
2838 client's cache to show updates */
2840 printer
.info_2
->changeid
= rev_changeid();
2843 * Because one day someone will ask:
2844 * NT->NT An admin connection to a remote
2845 * printer show changes imeediately in
2846 * the properities dialog
2848 * A non-admin connection will only show the
2849 * changes after viewing the properites page
2850 * 2 times. Seems to be related to a
2851 * race condition in the client between the spooler
2852 * updating the local cache and the Explorer.exe GUI
2853 * actually displaying the properties.
2855 * This is fixed in Win2k. admin/non-admin
2856 * connections both display changes immediately.
2861 result
=update_a_printer_2(printer
.info_2
);
2865 result
=WERR_UNKNOWN_LEVEL
;
2872 /****************************************************************************
2873 Initialize printer devmode & data with previously saved driver init values.
2874 ****************************************************************************/
2876 static BOOL
set_driver_init_2(NT_PRINTER_INFO_LEVEL_2
*info_ptr
)
2880 TDB_DATA kbuf
, dbuf
;
2881 NT_PRINTER_PARAM
*current
;
2882 NT_PRINTER_INFO_LEVEL_2 info
;
2885 * Delete any printer data 'specifics' already set. When called for driver
2886 * replace, there will generally be some, but during an add printer, there
2887 * should not be any (if there are delete them).
2889 while ( (current
=info_ptr
->specific
) != NULL
) {
2890 info_ptr
->specific
=current
->next
;
2891 SAFE_FREE(current
->data
);
2897 slprintf(key
, sizeof(key
)-1, "%s%s", DRIVER_INIT_PREFIX
, info_ptr
->drivername
);
2898 dos_to_unix(key
); /* Convert key to unix-codepage */
2901 kbuf
.dsize
= strlen(key
)+1;
2903 dbuf
= tdb_fetch(tdb_drivers
, kbuf
);
2906 * When changing to a driver that has no init info in the tdb, remove
2907 * the previous drivers init info and leave the new on blank.
2909 free_nt_devicemode(&info_ptr
->devmode
);
2914 * Get the saved DEVMODE..
2916 len
+= unpack_devicemode(&info
.devmode
,dbuf
.dptr
+len
, dbuf
.dsize
-len
);
2919 * The saved DEVMODE contains the devicename from the printer used during
2920 * the initialization save. Change it to reflect the new printer.
2922 ZERO_STRUCT(info
.devmode
->devicename
);
2923 fstrcpy(info
.devmode
->devicename
, info_ptr
->printername
);
2927 * NT/2k does not change out the entire DeviceMode of a printer
2928 * when changing the driver. Only the driverextra, private, &
2929 * driverversion fields. --jerry (Thu Mar 14 08:58:43 CST 2002)
2931 * Later e4xamination revealed that Windows NT/2k does reset the
2932 * the printer's device mode, bit **only** when you change a
2933 * property of the device mode such as the page orientation.
2940 * Bind the saved DEVMODE to the new the printer.
2942 free_nt_devicemode(&info_ptr
->devmode
);
2943 info_ptr
->devmode
= info
.devmode
;
2945 /* copy the entire devmode if we currently don't have one */
2947 if (!info_ptr
->devmode
) {
2948 DEBUG(10,("set_driver_init_2: Current Devmode is NULL. Copying entire Device Mode\n"));
2949 info_ptr
->devmode
= info
.devmode
;
2952 /* only set the necessary fields */
2954 DEBUG(10,("set_driver_init_2: Setting driverversion [0x%x] and private data [0x%x]\n",
2955 info
.devmode
->driverversion
, info
.devmode
->driverextra
));
2957 info_ptr
->devmode
->driverversion
= info
.devmode
->driverversion
;
2959 SAFE_FREE(info_ptr
->devmode
->private);
2960 info_ptr
->devmode
->private = NULL
;
2962 if (info
.devmode
->driverversion
)
2963 info_ptr
->devmode
->private = memdup(info
.devmode
->private, info
.devmode
->driverversion
);
2965 free_nt_devicemode(&info
.devmode
);
2969 DEBUG(10,("set_driver_init_2: Set printer [%s] init DEVMODE for driver [%s]\n",
2970 info_ptr
->printername
, info_ptr
->drivername
));
2973 * Add the printer data 'specifics' to the new printer
2975 len
+= unpack_specifics(&info_ptr
->specific
,dbuf
.dptr
+len
, dbuf
.dsize
-len
);
2977 SAFE_FREE(dbuf
.dptr
);
2982 /****************************************************************************
2983 Initialize printer devmode & data with previously saved driver init values.
2984 When a printer is created using AddPrinter, the drivername bound to the
2985 printer is used to lookup previously saved driver initialization info, which
2986 is bound to the new printer.
2987 ****************************************************************************/
2989 BOOL
set_driver_init(NT_PRINTER_INFO_LEVEL
*printer
, uint32 level
)
2991 BOOL result
= False
;
2996 result
= set_driver_init_2(printer
->info_2
);
3000 DEBUG(0,("set_driver_init: Programmer's error! Unknown driver_init level [%d]\n",
3008 /****************************************************************************
3009 Delete driver init data stored for a specified driver
3010 ****************************************************************************/
3012 BOOL
del_driver_init(char *drivername
)
3017 if (!drivername
|| !*drivername
) {
3018 DEBUG(3,("del_driver_init: No drivername specified!\n"));
3022 slprintf(key
, sizeof(key
)-1, "%s%s", DRIVER_INIT_PREFIX
, drivername
);
3023 dos_to_unix(key
); /* Convert key to unix-codepage */
3026 kbuf
.dsize
= strlen(key
)+1;
3028 DEBUG(6,("del_driver_init: Removing driver init data for [%s]\n", drivername
));
3030 return (tdb_delete(tdb_drivers
, kbuf
) == 0);
3033 /****************************************************************************
3034 Pack up the DEVMODE and specifics for a printer into a 'driver init' entry
3035 in the tdb. Note: this is different from the driver entry and the printer
3036 entry. There should be a single driver init entry for each driver regardless
3037 of whether it was installed from NT or 2K. Technically, they should be
3038 different, but they work out to the same struct.
3039 ****************************************************************************/
3041 static uint32
update_driver_init_2(NT_PRINTER_INFO_LEVEL_2
*info
)
3045 int buflen
, len
, ret
;
3046 TDB_DATA kbuf
, dbuf
;
3053 len
+= pack_devicemode(info
->devmode
, buf
+len
, buflen
-len
);
3055 len
+= pack_specifics(info
->specific
, buf
+len
, buflen
-len
);
3057 if (buflen
!= len
) {
3060 tb
= (char *)Realloc(buf
, len
);
3062 DEBUG(0, ("update_driver_init_2: failed to enlarge buffer!\n"));
3071 slprintf(key
, sizeof(key
)-1, "%s%s", DRIVER_INIT_PREFIX
, info
->drivername
);
3072 dos_to_unix(key
); /* Convert key to unix-codepage */
3075 kbuf
.dsize
= strlen(key
)+1;
3079 ret
= tdb_store(tdb_drivers
, kbuf
, dbuf
, TDB_REPLACE
);
3083 DEBUG(8, ("update_driver_init_2: error updating printer init to tdb on disk\n"));
3087 DEBUG(10,("update_driver_init_2: Saved printer [%s] init DEVMODE & specifics for driver [%s]\n",
3088 info
->sharename
, info
->drivername
));
3093 /****************************************************************************
3094 Update (i.e. save) the driver init info (DEVMODE and specifics) for a printer
3095 ****************************************************************************/
3097 uint32
update_driver_init(NT_PRINTER_INFO_LEVEL printer
, uint32 level
)
3101 dump_a_printer(printer
, level
);
3107 result
=update_driver_init_2(printer
.info_2
);
3118 /****************************************************************************
3119 Convert the printer data value, a REG_BINARY array, into an initialization
3120 DEVMODE. Note: the array must be parsed as if it was a DEVMODE in an rpc...
3121 got to keep the endians happy :).
3122 ****************************************************************************/
3124 static BOOL
convert_driver_init(NT_PRINTER_PARAM
*param
, TALLOC_CTX
*ctx
, NT_DEVICEMODE
*nt_devmode
)
3126 BOOL result
= False
;
3130 ZERO_STRUCT(devmode
);
3132 prs_init(&ps
, 0, ctx
, UNMARSHALL
);
3133 ps
.data_p
= (char *)param
->data
;
3134 ps
.buffer_size
= param
->data_len
;
3136 if (spoolss_io_devmode("phantom DEVMODE", &ps
, 0, &devmode
))
3137 result
= convert_devicemode("", &devmode
, &nt_devmode
);
3139 DEBUG(10,("convert_driver_init: error parsing DEVMODE\n"));
3144 /****************************************************************************
3145 Set the DRIVER_INIT info in the tdb. Requires Win32 client code that:
3147 1. Use the driver's config DLL to this UNC printername and:
3148 a. Call DrvPrintEvent with PRINTER_EVENT_INITIALIZE
3149 b. Call DrvConvertDevMode with CDM_DRIVER_DEFAULT to get default DEVMODE
3150 2. Call SetPrinterData with the 'magic' key and the DEVMODE as data.
3152 The last step triggers saving the "driver initialization" information for
3153 this printer into the tdb. Later, new printers that use this driver will
3154 have this initialization information bound to them. This simulates the
3155 driver initialization, as if it had run on the Samba server (as it would
3158 The Win32 client side code requirement sucks! But until we can run arbitrary
3159 Win32 printer driver code on any Unix that Samba runs on, we are stuck with it.
3161 It would have been easier to use SetPrinter because all the UNMARSHALLING of
3162 the DEVMODE is done there, but 2K/XP clients do not set the DEVMODE... think
3163 about it and you will realize why. JRR 010720
3164 ****************************************************************************/
3166 static WERROR
save_driver_init_2(NT_PRINTER_INFO_LEVEL
*printer
, NT_PRINTER_PARAM
*param
)
3168 WERROR status
= WERR_OK
;
3169 TALLOC_CTX
*ctx
= NULL
;
3170 NT_DEVICEMODE
*nt_devmode
= NULL
;
3171 NT_DEVICEMODE
*tmp_devmode
= printer
->info_2
->devmode
;
3174 * When the DEVMODE is already set on the printer, don't try to unpack it.
3177 if (!printer
->info_2
->devmode
&& param
->data_len
) {
3179 * Set devmode on printer info, so entire printer initialization can be
3183 if ((ctx
= talloc_init()) == NULL
)
3186 if ((nt_devmode
= (NT_DEVICEMODE
*)malloc(sizeof(NT_DEVICEMODE
))) == NULL
) {
3187 status
= WERR_NOMEM
;
3191 ZERO_STRUCTP(nt_devmode
);
3194 * The DEVMODE is held in the 'data' component of the param in raw binary.
3195 * Convert it to to a devmode structure
3197 if (!convert_driver_init(param
, ctx
, nt_devmode
)) {
3198 DEBUG(10,("save_driver_init_2: error converting DEVMODE\n"));
3199 status
= WERR_INVALID_PARAM
;
3203 printer
->info_2
->devmode
= nt_devmode
;
3207 * Pack up and add (or update) the DEVMODE and any current printer data to
3208 * a 'driver init' element in the tdb
3212 if (update_driver_init(*printer
, 2)!=0) {
3213 DEBUG(10,("save_driver_init_2: error updating DEVMODE\n"));
3214 status
= WERR_NOMEM
;
3219 * If driver initialization info was successfully saved, set the current
3220 * printer to match it. This allows initialization of the current printer
3221 * as well as the driver.
3223 status
= mod_a_printer(*printer
, 2);
3224 if (!W_ERROR_IS_OK(status
)) {
3225 DEBUG(10,("save_driver_init_2: error setting DEVMODE on printer [%s]\n",
3226 printer
->info_2
->printername
));
3230 srv_spoolss_sendnotify(p
, handle
);
3234 talloc_destroy(ctx
);
3236 SAFE_FREE(nt_devmode
->private);
3237 SAFE_FREE(nt_devmode
);
3238 printer
->info_2
->devmode
= tmp_devmode
;
3243 /****************************************************************************
3244 Update the driver init info (DEVMODE and specifics) for a printer
3245 ****************************************************************************/
3247 WERROR
save_driver_init(NT_PRINTER_INFO_LEVEL
*printer
, uint32 level
, NT_PRINTER_PARAM
*param
)
3249 WERROR status
= WERR_OK
;
3255 status
=save_driver_init_2(printer
, param
);
3259 status
=WERR_UNKNOWN_LEVEL
;
3266 /****************************************************************************
3267 Get a NT_PRINTER_INFO_LEVEL struct. It returns malloced memory.
3268 ****************************************************************************/
3270 WERROR
get_a_printer(NT_PRINTER_INFO_LEVEL
**pp_printer
, uint32 level
, fstring sharename
)
3273 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
3277 DEBUG(10,("get_a_printer: [%s] level %u\n", sharename
, (unsigned int)level
));
3283 if ((printer
= (NT_PRINTER_INFO_LEVEL
*)malloc(sizeof(NT_PRINTER_INFO_LEVEL
))) == NULL
) {
3284 DEBUG(0,("get_a_printer: malloc fail.\n"));
3287 ZERO_STRUCTP(printer
);
3288 result
=get_a_printer_2(&printer
->info_2
, sharename
);
3289 if (W_ERROR_IS_OK(result
)) {
3290 dump_a_printer(*printer
, level
);
3291 *pp_printer
= printer
;
3298 result
=WERR_UNKNOWN_LEVEL
;
3302 DEBUG(10,("get_a_printer: [%s] level %u returning %s\n", sharename
, (unsigned int)level
, dos_errstr(result
)));
3307 /****************************************************************************
3308 Deletes a NT_PRINTER_INFO_LEVEL struct.
3309 ****************************************************************************/
3311 uint32
free_a_printer(NT_PRINTER_INFO_LEVEL
**pp_printer
, uint32 level
)
3314 NT_PRINTER_INFO_LEVEL
*printer
= *pp_printer
;
3316 DEBUG(104,("freeing a printer at level [%d]\n", level
));
3318 if (printer
== NULL
)
3325 if (printer
->info_2
!= NULL
)
3327 free_nt_printer_info_level_2(&printer
->info_2
);
3341 SAFE_FREE(*pp_printer
);
3345 /****************************************************************************
3346 ****************************************************************************/
3347 uint32
add_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver
, uint32 level
)
3350 DEBUG(104,("adding a printer at level [%d]\n", level
));
3351 dump_a_printer_driver(driver
, level
);
3357 result
=add_a_printer_driver_3(driver
.info_3
);
3363 result
=add_a_printer_driver_6(driver
.info_6
);
3373 /****************************************************************************
3374 ****************************************************************************/
3375 WERROR
get_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL
*driver
, uint32 level
,
3376 fstring printername
, fstring architecture
, uint32 version
)
3384 result
=get_a_printer_driver_3(&driver
->info_3
, printername
, architecture
, version
);
3392 if (W_ERROR_IS_OK(result
))
3393 dump_a_printer_driver(*driver
, level
);
3397 /****************************************************************************
3398 ****************************************************************************/
3399 uint32
free_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver
, uint32 level
)
3407 NT_PRINTER_DRIVER_INFO_LEVEL_3
*info3
;
3408 if (driver
.info_3
!= NULL
)
3410 info3
=driver
.info_3
;
3411 SAFE_FREE(info3
->dependentfiles
);
3412 ZERO_STRUCTP(info3
);
3424 NT_PRINTER_DRIVER_INFO_LEVEL_6
*info6
;
3425 if (driver
.info_6
!= NULL
)
3427 info6
=driver
.info_6
;
3428 SAFE_FREE(info6
->dependentfiles
);
3429 SAFE_FREE(info6
->previousnames
);
3430 ZERO_STRUCTP(info6
);
3448 /****************************************************************************
3449 Determine whether or not a particular driver is currently assigned
3451 ****************************************************************************/
3452 BOOL
printer_driver_in_use (char *arch
, char *driver
)
3454 TDB_DATA kbuf
, newkey
, dbuf
;
3455 NT_PRINTER_INFO_LEVEL_2 info
;
3459 if (!nt_printing_init())
3462 DEBUG(5,("printer_driver_in_use: Beginning search through printers.tdb...\n"));
3464 /* loop through the printers.tdb and check for the drivername */
3465 for (kbuf
= tdb_firstkey(tdb_printers
); kbuf
.dptr
;
3466 newkey
= tdb_nextkey(tdb_printers
, kbuf
), safe_free(kbuf
.dptr
), kbuf
=newkey
)
3469 dbuf
= tdb_fetch(tdb_printers
, kbuf
);
3473 if (strncmp(kbuf
.dptr
, PRINTERS_PREFIX
, strlen(PRINTERS_PREFIX
)) != 0)
3476 ret
= tdb_unpack(dbuf
.dptr
, dbuf
.dsize
, "dddddddddddfffffPfffff",
3479 &info
.default_priority
,
3496 info
.printprocessor
,
3500 SAFE_FREE(dbuf
.dptr
);
3503 DEBUG (0,("printer_driver_in_use: tdb_unpack failed for printer %s\n",
3508 DEBUG (10,("printer_driver_in_use: Printer - %s (%s)\n",
3509 info
.printername
, info
.drivername
));
3511 if (strcmp(info
.drivername
, driver
) == 0)
3513 DEBUG(5,("printer_driver_in_use: Printer %s using %s\n",
3514 info
.printername
, driver
));
3518 DEBUG(5,("printer_driver_in_use: Completed search through printers.tdb...\n"));
3522 /* report that the driver is in use by default */
3526 /****************************************************************************
3527 Remove a printer driver from the TDB. This assumes that the the driver was
3528 previously looked up.
3529 ***************************************************************************/
3530 WERROR
delete_printer_driver (NT_PRINTER_DRIVER_INFO_LEVEL_3
*i
)
3537 get_short_archi(arch
, i
->environment
);
3538 slprintf(key
, sizeof(key
)-1, "%s%s/%d/%s", DRIVERS_PREFIX
,
3539 arch
, i
->cversion
, i
->name
);
3540 DEBUG(5,("delete_printer_driver: key = [%s]\n", key
));
3543 kbuf
.dsize
=strlen(key
)+1;
3545 if (tdb_delete(tdb_drivers
, kbuf
) == -1) {
3546 DEBUG (0,("delete_printer_driver: fail to delete %s!\n", key
));
3547 return WERR_ACCESS_DENIED
;
3550 DEBUG(5,("delete_printer_driver: [%s] driver delete successful.\n",
3555 /****************************************************************************
3556 ****************************************************************************/
3557 BOOL
get_specific_param_by_index(NT_PRINTER_INFO_LEVEL printer
, uint32 level
, uint32 param_index
,
3558 fstring value
, uint8
**data
, uint32
*type
, uint32
*len
)
3560 /* right now that's enough ! */
3561 NT_PRINTER_PARAM
*param
;
3564 param
=printer
.info_2
->specific
;
3566 while (param
!= NULL
&& i
< param_index
) {
3574 /* exited because it exist */
3576 StrnCpy(value
, param
->value
, sizeof(fstring
)-1);
3577 *data
=(uint8
*)malloc(param
->data_len
*sizeof(uint8
));
3580 ZERO_STRUCTP(*data
);
3581 memcpy(*data
, param
->data
, param
->data_len
);
3582 *len
=param
->data_len
;
3586 /****************************************************************************
3587 ****************************************************************************/
3588 BOOL
get_specific_param(NT_PRINTER_INFO_LEVEL printer
, uint32 level
,
3589 fstring value
, uint8
**data
, uint32
*type
, uint32
*len
)
3591 /* right now that's enough ! */
3592 NT_PRINTER_PARAM
*param
;
3594 DEBUG(10, ("get_specific_param\n"));
3596 param
=printer
.info_2
->specific
;
3598 while (param
!= NULL
)
3600 #if 1 /* JRA - I think this should be case insensitive.... */
3601 if ( strequal(value
, param
->value
)
3603 if ( !strcmp(value
, param
->value
)
3605 && strlen(value
)==strlen(param
->value
))
3613 DEBUGADD(10, ("get_specific_param: found one param\n"));
3614 /* exited because it exist */
3617 *data
=(uint8
*)malloc(param
->data_len
*sizeof(uint8
));
3620 memcpy(*data
, param
->data
, param
->data_len
);
3621 *len
=param
->data_len
;
3623 DEBUGADD(10, ("get_specific_param: exit true\n"));
3626 DEBUGADD(10, ("get_specific_param: exit false\n"));
3630 /****************************************************************************
3631 Store a security desc for a printer.
3632 ****************************************************************************/
3634 WERROR
nt_printing_setsec(char *printername
, SEC_DESC_BUF
*secdesc_ctr
)
3636 SEC_DESC_BUF
*new_secdesc_ctr
= NULL
;
3637 SEC_DESC_BUF
*old_secdesc_ctr
= NULL
;
3639 TALLOC_CTX
*mem_ctx
= NULL
;
3643 mem_ctx
= talloc_init();
3644 if (mem_ctx
== NULL
)
3647 /* The old owner and group sids of the security descriptor are not
3648 present when new ACEs are added or removed by changing printer
3649 permissions through NT. If they are NULL in the new security
3650 descriptor then copy them over from the old one. */
3652 if (!secdesc_ctr
->sec
->owner_sid
|| !secdesc_ctr
->sec
->grp_sid
) {
3653 DOM_SID
*owner_sid
, *group_sid
;
3654 SEC_ACL
*dacl
, *sacl
;
3655 SEC_DESC
*psd
= NULL
;
3658 nt_printing_getsec(mem_ctx
, printername
, &old_secdesc_ctr
);
3660 /* Pick out correct owner and group sids */
3662 owner_sid
= secdesc_ctr
->sec
->owner_sid
?
3663 secdesc_ctr
->sec
->owner_sid
:
3664 old_secdesc_ctr
->sec
->owner_sid
;
3666 group_sid
= secdesc_ctr
->sec
->grp_sid
?
3667 secdesc_ctr
->sec
->grp_sid
:
3668 old_secdesc_ctr
->sec
->grp_sid
;
3670 dacl
= secdesc_ctr
->sec
->dacl
?
3671 secdesc_ctr
->sec
->dacl
:
3672 old_secdesc_ctr
->sec
->dacl
;
3674 sacl
= secdesc_ctr
->sec
->sacl
?
3675 secdesc_ctr
->sec
->sacl
:
3676 old_secdesc_ctr
->sec
->sacl
;
3678 /* Make a deep copy of the security descriptor */
3680 psd
= make_sec_desc(mem_ctx
, secdesc_ctr
->sec
->revision
,
3681 owner_sid
, group_sid
,
3686 new_secdesc_ctr
= make_sec_desc_buf(mem_ctx
, size
, psd
);
3689 if (!new_secdesc_ctr
) {
3690 new_secdesc_ctr
= secdesc_ctr
;
3693 /* Store the security descriptor in a tdb */
3695 prs_init(&ps
, (uint32
)sec_desc_size(new_secdesc_ctr
->sec
) +
3696 sizeof(SEC_DESC_BUF
), mem_ctx
, MARSHALL
);
3698 if (!sec_io_desc_buf("nt_printing_setsec", &new_secdesc_ctr
,
3700 status
= WERR_BADFUNC
;
3704 slprintf(key
, sizeof(key
)-1, "SECDESC/%s", printername
);
3706 if (tdb_prs_store(tdb_printers
, key
, &ps
)==0) {
3709 DEBUG(1,("Failed to store secdesc for %s\n", printername
));
3710 status
= WERR_BADFUNC
;
3713 /* Free malloc'ed memory */
3719 talloc_destroy(mem_ctx
);
3723 /****************************************************************************
3724 Construct a default security descriptor buffer for a printer.
3725 ****************************************************************************/
3727 static SEC_DESC_BUF
*construct_default_printer_sdb(TALLOC_CTX
*ctx
)
3729 extern DOM_SID global_sam_sid
;
3732 SEC_ACL
*psa
= NULL
;
3733 SEC_DESC_BUF
*sdb
= NULL
;
3734 SEC_DESC
*psd
= NULL
;
3737 enum SID_NAME_USE name_type
;
3740 /* Create an ACE where Everyone is allowed to print */
3742 init_sec_access(&sa
, PRINTER_ACE_PRINT
);
3743 init_sec_ace(&ace
[0], &global_sid_World
, SEC_ACE_TYPE_ACCESS_ALLOWED
,
3744 sa
, SEC_ACE_FLAG_CONTAINER_INHERIT
);
3746 /* Make the security descriptor owned by the Administrators group
3747 on the PDC of the domain. */
3749 /* Note that for hysterical raisins, the argument to
3750 secrets_fetch_domain_sid() must be in dos codepage format.
3753 fstrcpy(dos_domain
, lp_workgroup());
3754 unix_to_dos(dos_domain
);
3756 if (secrets_fetch_domain_sid(dos_domain
, &owner_sid
)) {
3757 sid_append_rid(&owner_sid
, DOMAIN_USER_RID_ADMIN
);
3760 /* Backup plan - make printer owned by admins or root.
3761 This should emulate a lanman printer as security
3762 settings can't be changed. */
3764 if (!lookup_name("root", &owner_sid
, &name_type
)) {
3765 sid_copy(&owner_sid
, &global_sam_sid
);
3766 sid_append_rid(&owner_sid
, DOMAIN_USER_RID_ADMIN
);
3770 init_sec_access(&sa
, PRINTER_ACE_FULL_CONTROL
);
3771 init_sec_ace(&ace
[1], &owner_sid
, SEC_ACE_TYPE_ACCESS_ALLOWED
,
3772 sa
, SEC_ACE_FLAG_OBJECT_INHERIT
|
3773 SEC_ACE_FLAG_INHERIT_ONLY
);
3775 init_sec_access(&sa
, PRINTER_ACE_FULL_CONTROL
);
3776 init_sec_ace(&ace
[2], &owner_sid
, SEC_ACE_TYPE_ACCESS_ALLOWED
,
3777 sa
, SEC_ACE_FLAG_CONTAINER_INHERIT
);
3779 /* The ACL revision number in rpc_secdesc.h differs from the one
3780 created by NT when setting ACE entries in printer
3781 descriptors. NT4 complains about the property being edited by a
3784 if ((psa
= make_sec_acl(ctx
, NT4_ACL_REVISION
, 3, ace
)) != NULL
) {
3785 psd
= make_sec_desc(ctx
, SEC_DESC_REVISION
,
3787 NULL
, psa
, &sd_size
);
3791 DEBUG(0,("construct_default_printer_sd: Failed to make SEC_DESC.\n"));
3795 sdb
= make_sec_desc_buf(ctx
, sd_size
, psd
);
3797 DEBUG(4,("construct_default_printer_sdb: size = %u.\n",
3798 (unsigned int)sd_size
));
3803 /****************************************************************************
3804 Get a security desc for a printer.
3805 ****************************************************************************/
3807 BOOL
nt_printing_getsec(TALLOC_CTX
*ctx
, char *printername
, SEC_DESC_BUF
**secdesc_ctr
)
3813 if ((temp
= strchr(printername
+ 2, '\\'))) {
3814 printername
= temp
+ 1;
3817 /* Fetch security descriptor from tdb */
3819 slprintf(key
, sizeof(key
)-1, "SECDESC/%s", printername
);
3821 if (tdb_prs_fetch(tdb_printers
, key
, &ps
, ctx
)!=0 ||
3822 !sec_io_desc_buf("nt_printing_getsec", secdesc_ctr
, &ps
, 1)) {
3824 DEBUG(4,("using default secdesc for %s\n", printername
));
3826 if (!(*secdesc_ctr
= construct_default_printer_sdb(ctx
))) {
3830 /* Save default security descriptor for later */
3832 prs_init(&ps
, (uint32
)sec_desc_size((*secdesc_ctr
)->sec
) +
3833 sizeof(SEC_DESC_BUF
), ctx
, MARSHALL
);
3835 if (sec_io_desc_buf("nt_printing_setsec", secdesc_ctr
, &ps
, 1))
3836 tdb_prs_store(tdb_printers
, key
, &ps
);
3843 /* If security descriptor is owned by S-1-1-0 and winbindd is up,
3844 this security descriptor has been created when winbindd was
3845 down. Take ownership of security descriptor. */
3847 if (sid_equal((*secdesc_ctr
)->sec
->owner_sid
, &global_sid_World
)) {
3849 enum SID_NAME_USE name_type
;
3851 /* Change sd owner to workgroup administrator */
3853 if (winbind_lookup_name(NULL
, lp_workgroup(), &owner_sid
,
3855 SEC_DESC_BUF
*new_secdesc_ctr
= NULL
;
3856 SEC_DESC
*psd
= NULL
;
3861 sid_append_rid(&owner_sid
, DOMAIN_USER_RID_ADMIN
);
3863 psd
= make_sec_desc(ctx
, (*secdesc_ctr
)->sec
->revision
,
3865 (*secdesc_ctr
)->sec
->grp_sid
,
3866 (*secdesc_ctr
)->sec
->sacl
,
3867 (*secdesc_ctr
)->sec
->dacl
,
3870 new_secdesc_ctr
= make_sec_desc_buf(ctx
, size
, psd
);
3872 /* Swap with other one */
3874 *secdesc_ctr
= new_secdesc_ctr
;
3878 nt_printing_setsec(printername
, *secdesc_ctr
);
3882 if (DEBUGLEVEL
>= 10) {
3883 SEC_ACL
*the_acl
= (*secdesc_ctr
)->sec
->dacl
;
3886 DEBUG(10, ("secdesc_ctr for %s has %d aces:\n",
3887 printername
, the_acl
->num_aces
));
3889 for (i
= 0; i
< the_acl
->num_aces
; i
++) {
3892 sid_to_string(sid_str
, &the_acl
->ace
[i
].trustee
);
3894 DEBUG(10, ("%s %d %d 0x%08x\n", sid_str
,
3895 the_acl
->ace
[i
].type
, the_acl
->ace
[i
].flags
,
3896 the_acl
->ace
[i
].info
.mask
));
3906 1: level not implemented
3907 2: file doesn't exist
3908 3: can't allocate memory
3909 4: can't free memory
3910 5: non existant struct
3914 A printer and a printer driver are 2 different things.
3915 NT manages them separatelly, Samba does the same.
3916 Why ? Simply because it's easier and it makes sense !
3918 Now explanation: You have 3 printers behind your samba server,
3919 2 of them are the same make and model (laser A and B). But laser B
3920 has an 3000 sheet feeder and laser A doesn't such an option.
3921 Your third printer is an old dot-matrix model for the accounting :-).
3923 If the /usr/local/samba/lib directory (default dir), you will have
3924 5 files to describe all of this.
3926 3 files for the printers (1 by printer):
3929 NTprinter_accounting
3930 2 files for the drivers (1 for the laser and 1 for the dot matrix)
3931 NTdriver_printer model X
3932 NTdriver_printer model Y
3934 jfm: I should use this comment for the text file to explain
3935 same thing for the forms BTW.
3936 Je devrais mettre mes commentaires en francais, ca serait mieux :-)
3940 /* Convert generic access rights to printer object specific access rights.
3941 It turns out that NT4 security descriptors use generic access rights and
3942 NT5 the object specific ones. */
3944 void map_printer_permissions(SEC_DESC
*sd
)
3948 for (i
= 0; sd
->dacl
&& i
< sd
->dacl
->num_aces
; i
++) {
3949 se_map_generic(&sd
->dacl
->ace
[i
].info
.mask
,
3950 &printer_generic_mapping
);
3954 /****************************************************************************
3955 Check a user has permissions to perform the given operation. We use the
3956 permission constants defined in include/rpc_spoolss.h to check the various
3957 actions we perform when checking printer access.
3959 PRINTER_ACCESS_ADMINISTER:
3960 print_queue_pause, print_queue_resume, update_printer_sec,
3961 update_printer, spoolss_addprinterex_level_2,
3962 _spoolss_setprinterdata
3967 JOB_ACCESS_ADMINISTER:
3968 print_job_delete, print_job_pause, print_job_resume,
3971 ****************************************************************************/
3972 BOOL
print_access_check(struct current_user
*user
, int snum
, int access_type
)
3974 SEC_DESC_BUF
*secdesc
= NULL
;
3975 uint32 access_granted
;
3979 TALLOC_CTX
*mem_ctx
= NULL
;
3980 extern struct current_user current_user
;
3982 /* If user is NULL then use the current_user structure */
3985 user
= ¤t_user
;
3987 /* Always allow root or printer admins to do anything */
3989 if (user
->uid
== 0 ||
3990 user_in_list(uidtoname(user
->uid
), lp_printer_admin(snum
))) {
3994 /* Get printer name */
3996 pname
= PRINTERNAME(snum
);
3998 if (!pname
|| !*pname
) {
4003 /* Get printer security descriptor */
4005 if(!(mem_ctx
= talloc_init())) {
4010 nt_printing_getsec(mem_ctx
, pname
, &secdesc
);
4012 if (access_type
== JOB_ACCESS_ADMINISTER
) {
4013 SEC_DESC_BUF
*parent_secdesc
= secdesc
;
4015 /* Create a child security descriptor to check permissions
4016 against. This is because print jobs are child objects
4017 objects of a printer. */
4019 secdesc
= se_create_child_secdesc(mem_ctx
, parent_secdesc
->sec
, False
);
4021 /* Now this is the bit that really confuses me. The access
4022 type needs to be changed from JOB_ACCESS_ADMINISTER to
4023 PRINTER_ACCESS_ADMINISTER for this to work. Something
4024 to do with the child (job) object becoming like a
4027 access_type
= PRINTER_ACCESS_ADMINISTER
;
4032 map_printer_permissions(secdesc
->sec
);
4034 result
= se_access_check(secdesc
->sec
, user
->nt_user_token
, access_type
,
4035 &access_granted
, &status
);
4037 DEBUG(4, ("access check was %s\n", result
? "SUCCESS" : "FAILURE"));
4039 talloc_destroy(mem_ctx
);
4047 /****************************************************************************
4048 Check the time parameters allow a print operation.
4049 *****************************************************************************/
4051 BOOL
print_time_access_check(int snum
)
4053 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
4055 time_t now
= time(NULL
);
4059 if (!W_ERROR_IS_OK(get_a_printer(&printer
, 2, lp_servicename(snum
))))
4062 if (printer
->info_2
->starttime
== 0 && printer
->info_2
->untiltime
== 0)
4066 mins
= (uint32
)t
->tm_hour
*60 + (uint32
)t
->tm_min
;
4068 if (mins
>= printer
->info_2
->starttime
&& mins
<= printer
->info_2
->untiltime
)
4071 free_a_printer(&printer
, 2);
4079 #if 0 /* JERRY - not used */
4080 /****************************************************************************
4081 Attempt to write a default device.
4082 *****************************************************************************/
4084 WERROR
printer_write_default_dev(int snum
, const PRINTER_DEFAULT
*printer_default
)
4086 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
4090 * Don't bother if no default devicemode was sent.
4093 if (printer_default
->devmode_cont
.devmode
== NULL
)
4096 result
= get_a_printer(&printer
, 2, lp_servicename(snum
));
4097 if (!W_ERROR_IS_OK(result
)) return result
;
4100 * Just ignore it if we already have a devmode.
4103 if (printer
->info_2
->devmode
!= NULL
)
4107 * We don't have a devicemode and we're trying to write
4108 * one. Check we have the access needed.
4110 DEBUG(5,("printer_write_default_dev: access: %x\n", printer_default
->access_required
));
4112 if ( (printer_default
->access_required
& PRINTER_ACCESS_ADMINISTER
) !=
4113 PRINTER_ACCESS_ADMINISTER
) {
4114 DEBUG(5,("printer_write_default_dev: invalid request access to update: %x\n", printer_default
->access_required
));
4115 result
= WERR_ACCESS_DENIED
;
4119 if (!print_access_check(NULL
, snum
, PRINTER_ACCESS_ADMINISTER
)) {
4120 DEBUG(5,("printer_write_default_dev: Access denied for printer %s\n",
4121 lp_servicename(snum
) ));
4122 result
= WERR_ACCESS_DENIED
;
4123 /*result = NT_STATUS_NO_PROBLEMO;*/
4127 DEBUG(5,("printer_write_default_dev: updating, check OK.\n"));
4130 * Convert the on the wire devicemode format to the internal one.
4133 if (!convert_devicemode(printer
->info_2
->printername
,
4134 printer_default
->devmode_cont
.devmode
,
4135 &printer
->info_2
->devmode
)) {
4136 result
= WERR_NOMEM
;
4141 * Finally write back to the tdb.
4144 result
= mod_a_printer(*printer
, 2);
4148 free_a_printer(&printer
, 2);