2 * Unix SMB/Netbios 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 = {
51 STANDARD_MAPPING printer_std_mapping = {
58 /* We need one default form to support our default printer. Msoft adds the
59 forms it wants and in the ORDER it wants them (note: DEVMODE papersize is an
60 array index). Letter is always first, so (for the current code) additions
61 always put things in the correct order. */
62 static nt_forms_struct default_forms[] = {
63 {"Letter",0x1,0x34b5c,0x44368,0x0,0x0,0x34b5c,0x44368},
64 {"Letter Small",0x1,0x34b5c,0x44368,0x0,0x0,0x34b5c,0x44368},
65 {"Tabloid",0x1,0x44368,0x696b8,0x0,0x0,0x44368,0x696b8},
66 {"Ledger",0x1,0x696b8,0x44368,0x0,0x0,0x696b8,0x44368},
67 {"Legal",0x1,0x34b5c,0x56d10,0x0,0x0,0x34b5c,0x56d10},
68 {"Statement",0x1,0x221b4,0x34b5c,0x0,0x0,0x221b4,0x34b5c},
69 {"Executive",0x1,0x2cf56,0x411cc,0x0,0x0,0x2cf56,0x411cc},
70 {"A3",0x1,0x48828,0x668a0,0x0,0x0,0x48828,0x668a0},
71 {"A4",0x1,0x33450,0x48828,0x0,0x0,0x33450,0x48828},
72 {"A4 Small",0x1,0x33450,0x48828,0x0,0x0,0x33450,0x48828},
73 {"A5",0x1,0x24220,0x33450,0x0,0x0,0x24220,0x33450},
74 {"B4 (JIS)",0x1,0x3ebe8,0x58de0,0x0,0x0,0x3ebe8,0x58de0},
75 {"B5 (JIS)",0x1,0x2c6f0,0x3ebe8,0x0,0x0,0x2c6f0,0x3ebe8},
76 {"Folio",0x1,0x34b5c,0x509d8,0x0,0x0,0x34b5c,0x509d8},
77 {"Quarto",0x1,0x347d8,0x43238,0x0,0x0,0x347d8,0x43238},
78 {"10x14",0x1,0x3e030,0x56d10,0x0,0x0,0x3e030,0x56d10},
79 {"11x17",0x1,0x44368,0x696b8,0x0,0x0,0x44368,0x696b8},
80 {"Note",0x1,0x34b5c,0x44368,0x0,0x0,0x34b5c,0x44368},
81 {"Envelope #9",0x1,0x18079,0x37091,0x0,0x0,0x18079,0x37091},
82 {"Envelope #10",0x1,0x19947,0x3ae94,0x0,0x0,0x19947,0x3ae94},
83 {"Envelope #11",0x1,0x1be7c,0x40565,0x0,0x0,0x1be7c,0x40565},
84 {"Envelope #12",0x1,0x1d74a,0x44368,0x0,0x0,0x1d74a,0x44368},
85 {"Envelope #14",0x1,0x1f018,0x47504,0x0,0x0,0x1f018,0x47504},
86 {"C size sheet",0x1,0x696b8,0x886d0,0x0,0x0,0x696b8,0x886d0},
87 {"D size sheet",0x1,0x886d0,0xd2d70,0x0,0x0,0x886d0,0xd2d70},
88 {"E size sheet",0x1,0xd2d70,0x110da0,0x0,0x0,0xd2d70,0x110da0},
89 {"Envelope DL",0x1,0x1adb0,0x35b60,0x0,0x0,0x1adb0,0x35b60},
90 {"Envelope C5",0x1,0x278d0,0x37e88,0x0,0x0,0x278d0,0x37e88},
91 {"Envelope C3",0x1,0x4f1a0,0x6fd10,0x0,0x0,0x4f1a0,0x6fd10},
92 {"Envelope C4",0x1,0x37e88,0x4f1a0,0x0,0x0,0x37e88,0x4f1a0},
93 {"Envelope C6",0x1,0x1bd50,0x278d0,0x0,0x0,0x1bd50,0x278d0},
94 {"Envelope C65",0x1,0x1bd50,0x37e88,0x0,0x0,0x1bd50,0x37e88},
95 {"Envelope B4",0x1,0x3d090,0x562e8,0x0,0x0,0x3d090,0x562e8},
96 {"Envelope B5",0x1,0x2af80,0x3d090,0x0,0x0,0x2af80,0x3d090},
97 {"Envelope B6",0x1,0x2af80,0x1e848,0x0,0x0,0x2af80,0x1e848},
98 {"Envelope",0x1,0x1adb0,0x38270,0x0,0x0,0x1adb0,0x38270},
99 {"Envelope Monarch",0x1,0x18079,0x2e824,0x0,0x0,0x18079,0x2e824},
100 {"6 3/4 Envelope",0x1,0x167ab,0x284ec,0x0,0x0,0x167ab,0x284ec},
101 {"US Std Fanfold",0x1,0x5c3e1,0x44368,0x0,0x0,0x5c3e1,0x44368},
102 {"German Std Fanfold",0x1,0x34b5c,0x4a6a0,0x0,0x0,0x34b5c,0x4a6a0},
103 {"German Legal Fanfold",0x1,0x34b5c,0x509d8,0x0,0x0,0x34b5c,0x509d8},
104 {"B4 (ISO)",0x1,0x3d090,0x562e8,0x0,0x0,0x3d090,0x562e8},
105 {"Japanese Postcard",0x1,0x186a0,0x24220,0x0,0x0,0x186a0,0x24220},
106 {"9x11",0x1,0x37cf8,0x44368,0x0,0x0,0x37cf8,0x44368},
107 {"10x11",0x1,0x3e030,0x44368,0x0,0x0,0x3e030,0x44368},
108 {"15x11",0x1,0x5d048,0x44368,0x0,0x0,0x5d048,0x44368},
109 {"Envelope Invite",0x1,0x35b60,0x35b60,0x0,0x0,0x35b60,0x35b60},
110 {"Reserved48",0x1,0x1,0x1,0x0,0x0,0x1,0x1},
111 {"Reserved49",0x1,0x1,0x1,0x0,0x0,0x1,0x1},
112 {"Letter Extra",0x1,0x3ae94,0x4a6a0,0x0,0x0,0x3ae94,0x4a6a0},
113 {"Legal Extra",0x1,0x3ae94,0x5d048,0x0,0x0,0x3ae94,0x5d048},
114 {"Tabloid Extra",0x1,0x4a6a0,0x6f9f0,0x0,0x0,0x4a6a0,0x6f9f0},
115 {"A4 Extra",0x1,0x397c2,0x4eb16,0x0,0x0,0x397c2,0x4eb16},
116 {"Letter Transverse",0x1,0x34b5c,0x44368,0x0,0x0,0x34b5c,0x44368},
117 {"A4 Transverse",0x1,0x33450,0x48828,0x0,0x0,0x33450,0x48828},
118 {"Letter Extra Transverse",0x1,0x3ae94,0x4a6a0,0x0,0x0,0x3ae94,0x4a6a0},
119 {"Super A",0x1,0x376b8,0x56ea0,0x0,0x0,0x376b8,0x56ea0},
120 {"Super B",0x1,0x4a768,0x76e58,0x0,0x0,0x4a768,0x76e58},
121 {"Letter Plus",0x1,0x34b5c,0x4eb16,0x0,0x0,0x34b5c,0x4eb16},
122 {"A4 Plus",0x1,0x33450,0x50910,0x0,0x0,0x33450,0x50910},
123 {"A5 Transverse",0x1,0x24220,0x33450,0x0,0x0,0x24220,0x33450},
124 {"B5 (JIS) Transverse",0x1,0x2c6f0,0x3ebe8,0x0,0x0,0x2c6f0,0x3ebe8},
125 {"A3 Extra",0x1,0x4e9d0,0x6ca48,0x0,0x0,0x4e9d0,0x6ca48},
126 {"A5 Extra",0x1,0x2a7b0,0x395f8,0x0,0x0,0x2a7b0,0x395f8},
127 {"B5 (ISO) Extra",0x1,0x31128,0x43620,0x0,0x0,0x31128,0x43620},
128 {"A2",0x1,0x668a0,0x91050,0x0,0x0,0x668a0,0x91050},
129 {"A3 Transverse",0x1,0x48828,0x668a0,0x0,0x0,0x48828,0x668a0},
130 {"A3 Extra Transverse",0x1,0x4e9d0,0x6ca48,0x0,0x0,0x4e9d0,0x6ca48},
131 {"Japanese Double Postcard",0x1,0x30d40,0x24220,0x0,0x0,0x30d40,0x24220},
132 {"A6",0x1,0x19a28,0x24220,0x0,0x0,0x19a28,0x24220},
133 {"Japanese Envelope Kaku #2",0x1,0x3a980,0x510e0,0x0,0x0,0x3a980,0x510e0},
134 {"Japanese Envelope Kaku #3",0x1,0x34bc0,0x43a08,0x0,0x0,0x34bc0,0x43a08},
135 {"Japanese Envelope Chou #3",0x1,0x1d4c0,0x395f8,0x0,0x0,0x1d4c0,0x395f8},
136 {"Japanese Envelope Chou #4",0x1,0x15f90,0x320c8,0x0,0x0,0x15f90,0x320c8},
137 {"Letter Rotated",0x1,0x44368,0x34b5c,0x0,0x0,0x44368,0x34b5c},
138 {"A3 Rotated",0x1,0x668a0,0x48828,0x0,0x0,0x668a0,0x48828},
139 {"A4 Rotated",0x1,0x48828,0x33450,0x0,0x0,0x48828,0x33450},
140 {"A5 Rotated",0x1,0x33450,0x24220,0x0,0x0,0x33450,0x24220},
141 {"B4 (JIS) Rotated",0x1,0x58de0,0x3ebe8,0x0,0x0,0x58de0,0x3ebe8},
142 {"B5 (JIS) Rotated",0x1,0x3ebe8,0x2c6f0,0x0,0x0,0x3ebe8,0x2c6f0},
143 {"Japanese Postcard Rotated",0x1,0x24220,0x186a0,0x0,0x0,0x24220,0x186a0},
144 {"Double Japan Postcard Rotated",0x1,0x24220,0x30d40,0x0,0x0,0x24220,0x30d40},
145 {"A6 Rotated",0x1,0x24220,0x19a28,0x0,0x0,0x24220,0x19a28},
146 {"Japan Envelope Kaku #2 Rotated",0x1,0x510e0,0x3a980,0x0,0x0,0x510e0,0x3a980},
147 {"Japan Envelope Kaku #3 Rotated",0x1,0x43a08,0x34bc0,0x0,0x0,0x43a08, 0x34bc0},
148 {"Japan Envelope Chou #3 Rotated",0x1,0x395f8,0x1d4c0,0x0,0x0,0x395f8,0x1d4c0},
149 {"Japan Envelope Chou #4 Rotated",0x1,0x320c8,0x15f90,0x0,0x0,0x320c8,0x15f90},
150 {"B6 (JIS)",0x1,0x1f400,0x2c6f0,0x0,0x0,0x1f400,0x2c6f0},
151 {"B6 (JIS) Rotated",0x1,0x2c6f0,0x1f400,0x0,0x0,0x2c6f0,0x1f400},
152 {"12x11",0x1,0x4a724,0x443e1,0x0,0x0,0x4a724,0x443e1},
153 {"Japan Envelope You #4",0x1,0x19a28,0x395f8,0x0,0x0,0x19a28,0x395f8},
154 {"Japan Envelope You #4 Rotated",0x1,0x395f8,0x19a28,0x0,0x0,0x395f8,0x19a28},
155 {"PRC 16K",0x1,0x2de60,0x3f7a0,0x0,0x0,0x2de60,0x3f7a0},
156 {"PRC 32K",0x1,0x1fbd0,0x2cec0,0x0,0x0,0x1fbd0,0x2cec0},
157 {"PRC 32K(Big)",0x1,0x222e0,0x318f8,0x0,0x0,0x222e0,0x318f8},
158 {"PRC Envelope #1",0x1,0x18e70,0x28488,0x0,0x0,0x18e70,0x28488},
159 {"PRC Envelope #2",0x1,0x18e70,0x2af80,0x0,0x0,0x18e70,0x2af80},
160 {"PRC Envelope #3",0x1,0x1e848,0x2af80,0x0,0x0,0x1e848,0x2af80},
161 {"PRC Envelope #4",0x1,0x1adb0,0x32c80,0x0,0x0,0x1adb0,0x32c80},
162 {"PRC Envelope #5",0x1,0x1adb0,0x35b60,0x0,0x0,0x1adb0,0x35b60},
163 {"PRC Envelope #6",0x1,0x1d4c0,0x38270,0x0,0x0,0x1d4c0,0x38270},
164 {"PRC Envelope #7",0x1,0x27100,0x38270,0x0,0x0,0x27100,0x38270},
165 {"PRC Envelope #8",0x1,0x1d4c0,0x4b708,0x0,0x0,0x1d4c0,0x4b708},
166 {"PRC Envelope #9",0x1,0x37e88,0x4f1a0,0x0,0x0,0x37e88,0x4f1a0},
167 {"PRC Envelope #10",0x1,0x4f1a0,0x6fd10,0x0,0x0,0x4f1a0,0x6fd10},
168 {"PRC 16K Rotated",0x1,0x3f7a0,0x2de60,0x0,0x0,0x3f7a0,0x2de60},
169 {"PRC 32K Rotated",0x1,0x2cec0,0x1fbd0,0x0,0x0,0x2cec0,0x1fbd0},
170 {"PRC 32K(Big) Rotated",0x1,0x318f8,0x222e0,0x0,0x0,0x318f8,0x222e0},
171 {"PRC Envelope #1 Rotated",0x1,0x28488,0x18e70,0x0,0x0,0x28488,0x18e70},
172 {"PRC Envelope #2 Rotated",0x1,0x2af80,0x18e70,0x0,0x0,0x2af80,0x18e70},
173 {"PRC Envelope #3 Rotated",0x1,0x2af80,0x1e848,0x0,0x0,0x2af80,0x1e848},
174 {"PRC Envelope #4 Rotated",0x1,0x32c80,0x1adb0,0x0,0x0,0x32c80,0x1adb0},
175 {"PRC Envelope #5 Rotated",0x1,0x35b60,0x1adb0,0x0,0x0,0x35b60,0x1adb0},
176 {"PRC Envelope #6 Rotated",0x1,0x38270,0x1d4c0,0x0,0x0,0x38270,0x1d4c0},
177 {"PRC Envelope #7 Rotated",0x1,0x38270,0x27100,0x0,0x0,0x38270,0x27100},
178 {"PRC Envelope #8 Rotated",0x1,0x4b708,0x1d4c0,0x0,0x0,0x4b708,0x1d4c0},
179 {"PRC Envelope #9 Rotated",0x1,0x4f1a0,0x37e88,0x0,0x0,0x4f1a0,0x37e88},
180 {"PRC Envelope #10 Rotated",0x1,0x6fd10,0x4f1a0,0x0,0x0,0x6fd10,0x4f1a0}
183 static BOOL upgrade_to_version_3(void)
185 TDB_DATA kbuf, newkey, dbuf;
187 DEBUG(0,("upgrade_to_version_3: upgrading print tdb's to version 3\n"));
189 for (kbuf = tdb_firstkey(tdb_drivers); kbuf.dptr;
190 newkey = tdb_nextkey(tdb_drivers, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
192 dbuf = tdb_fetch(tdb_drivers, kbuf);
194 if (strncmp(kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) == 0) {
195 DEBUG(0,("upgrade_to_version_3:moving form\n"));
196 if (tdb_store(tdb_forms, kbuf, dbuf, TDB_REPLACE) != 0) {
197 DEBUG(0,("upgrade_to_version_3: failed to move form. Error (%s).\n", tdb_errorstr(tdb_forms)));
200 if (tdb_delete(tdb_drivers, kbuf) != 0) {
201 DEBUG(0,("upgrade_to_version_3: failed to delete form. Error (%s)\n", tdb_errorstr(tdb_drivers)));
206 if (strncmp(kbuf.dptr, PRINTERS_PREFIX, strlen(PRINTERS_PREFIX)) == 0) {
207 DEBUG(0,("upgrade_to_version_3:moving printer\n"));
208 if (tdb_store(tdb_printers, kbuf, dbuf, TDB_REPLACE) != 0) {
209 DEBUG(0,("upgrade_to_version_3: failed to move printer. Error (%s)\n", tdb_errorstr(tdb_printers)));
212 if (tdb_delete(tdb_drivers, kbuf) != 0) {
213 DEBUG(0,("upgrade_to_version_3: failed to delete printer. Error (%s)\n", tdb_errorstr(tdb_drivers)));
218 if (strncmp(kbuf.dptr, SECDESC_PREFIX, strlen(SECDESC_PREFIX)) == 0) {
219 DEBUG(0,("upgrade_to_version_3:moving secdesc\n"));
220 if (tdb_store(tdb_printers, kbuf, dbuf, TDB_REPLACE) != 0) {
221 DEBUG(0,("upgrade_to_version_3: failed to move secdesc. Error (%s)\n", tdb_errorstr(tdb_printers)));
224 if (tdb_delete(tdb_drivers, kbuf) != 0) {
225 DEBUG(0,("upgrade_to_version_3: failed to delete secdesc. Error (%s)\n", tdb_errorstr(tdb_drivers)));
230 SAFE_FREE(dbuf.dptr);
236 /****************************************************************************
237 Open the NT printing tdb.
238 ****************************************************************************/
240 BOOL nt_printing_init(void)
242 static pid_t local_pid;
243 char *vstring = "INFO/version";
245 if (tdb_drivers && tdb_printers && tdb_forms && local_pid == sys_getpid())
248 tdb_drivers = tdb_open_log(lock_path("ntdrivers.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
250 DEBUG(0,("nt_printing_init: Failed to open nt drivers database %s (%s)\n",
251 lock_path("ntdrivers.tdb"), strerror(errno) ));
255 tdb_printers = tdb_open_log(lock_path("ntprinters.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
257 DEBUG(0,("nt_printing_init: Failed to open nt printers database %s (%s)\n",
258 lock_path("ntprinters.tdb"), strerror(errno) ));
262 tdb_forms = tdb_open_log(lock_path("ntforms.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
264 DEBUG(0,("nt_printing_init: Failed to open nt forms database %s (%s)\n",
265 lock_path("ntforms.tdb"), strerror(errno) ));
269 local_pid = sys_getpid();
271 /* handle a Samba upgrade */
272 tdb_lock_bystring(tdb_drivers, vstring);
276 /* Cope with byte-reversed older versions of the db. */
277 vers_id = tdb_fetch_int32(tdb_drivers, vstring);
278 if ((vers_id == NTDRIVERS_DATABASE_VERSION_2) || (IREV(vers_id) == NTDRIVERS_DATABASE_VERSION_2)) {
279 /* Written on a bigendian machine with old fetch_int code. Save as le. */
280 /* The only upgrade between V2 and V3 is to save the version in little-endian. */
281 tdb_store_int32(tdb_drivers, vstring, NTDRIVERS_DATABASE_VERSION);
282 vers_id = NTDRIVERS_DATABASE_VERSION;
285 if (vers_id != NTDRIVERS_DATABASE_VERSION) {
287 if ((vers_id == NTDRIVERS_DATABASE_VERSION_1) || (IREV(vers_id) == NTDRIVERS_DATABASE_VERSION_1)) {
288 if (!upgrade_to_version_3())
291 tdb_traverse(tdb_drivers, tdb_traverse_delete_fn, NULL);
293 tdb_store_int32(tdb_drivers, vstring, NTDRIVERS_DATABASE_VERSION);
296 tdb_unlock_bystring(tdb_drivers, vstring);
298 update_c_setprinter(True);
303 /*******************************************************************
304 tdb traversal function for counting printers.
305 ********************************************************************/
307 static int traverse_counting_printers(TDB_CONTEXT *t, TDB_DATA key,
308 TDB_DATA data, void *context)
310 int *printer_count = (int*)context;
312 if (memcmp(PRINTERS_PREFIX, key.dptr, sizeof(PRINTERS_PREFIX)-1) == 0) {
314 DEBUG(10,("traverse_counting_printers: printer = [%s] printer_count = %d\n", key.dptr, *printer_count));
320 /*******************************************************************
321 Update the spooler global c_setprinter. This variable is initialized
322 when the parent smbd starts with the number of existing printers. It
323 is monotonically increased by the current number of printers *after*
324 each add or delete printer RPC. Only Microsoft knows why... JRR020119
325 ********************************************************************/
327 uint32 update_c_setprinter(BOOL initialize)
330 int32 printer_count = 0;
332 tdb_lock_bystring(tdb_printers, GLOBAL_C_SETPRINTER);
334 /* Traverse the tdb, counting the printers */
335 tdb_traverse(tdb_printers, traverse_counting_printers, (void *)&printer_count);
337 /* If initializing, set c_setprinter to current printers count
338 * otherwise, bump it by the current printer count
341 c_setprinter = tdb_fetch_int32(tdb_printers, GLOBAL_C_SETPRINTER) + printer_count;
343 c_setprinter = printer_count;
345 DEBUG(10,("update_c_setprinter: c_setprinter = %u\n", (unsigned int)c_setprinter));
346 tdb_store_int32(tdb_printers, GLOBAL_C_SETPRINTER, c_setprinter);
348 tdb_unlock_bystring(tdb_printers, GLOBAL_C_SETPRINTER);
350 return (uint32)c_setprinter;
353 /*******************************************************************
354 Get the spooler global c_setprinter, accounting for initialization.
355 ********************************************************************/
357 uint32 get_c_setprinter(void)
359 int32 c_setprinter = tdb_fetch_int32(tdb_printers, GLOBAL_C_SETPRINTER);
361 if (c_setprinter == (int32)-1)
362 c_setprinter = update_c_setprinter(True);
364 DEBUG(10,("get_c_setprinter: c_setprinter = %d\n", c_setprinter));
366 return (uint32)c_setprinter;
369 /****************************************************************************
370 Get builtin form struct list.
371 ****************************************************************************/
373 int get_builtin_ntforms(nt_forms_struct **list)
375 *list = (nt_forms_struct *)memdup(&default_forms[0], sizeof(default_forms));
376 return sizeof(default_forms) / sizeof(default_forms[0]);
379 /****************************************************************************
380 get a builtin form struct
381 ****************************************************************************/
383 BOOL get_a_builtin_ntform(UNISTR2 *uni_formname,nt_forms_struct *form)
387 unistr2_to_ascii(form_name, uni_formname, sizeof(form_name)-1);
388 DEBUGADD(6,("Looking for builtin form %s \n", form_name));
389 count = sizeof(default_forms) / sizeof(default_forms[0]);
390 for (i=0;i<count;i++) {
391 if (strequal(form_name,default_forms[i].name)) {
392 DEBUGADD(6,("Found builtin form %s \n", form_name));
393 memcpy(form,&default_forms[i],sizeof(*form));
401 /****************************************************************************
402 get a form struct list
403 ****************************************************************************/
404 int get_ntforms(nt_forms_struct **list)
406 TDB_DATA kbuf, newkey, dbuf;
408 nt_forms_struct form;
413 for (kbuf = tdb_firstkey(tdb_forms);
415 newkey = tdb_nextkey(tdb_forms, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
416 if (strncmp(kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) != 0) continue;
418 dbuf = tdb_fetch(tdb_forms, kbuf);
419 if (!dbuf.dptr) continue;
421 fstrcpy(form.name, kbuf.dptr+strlen(FORMS_PREFIX));
422 ret = tdb_unpack(dbuf.dptr, dbuf.dsize, "dddddddd",
423 &i, &form.flag, &form.width, &form.length, &form.left,
424 &form.top, &form.right, &form.bottom);
425 SAFE_FREE(dbuf.dptr);
426 if (ret != dbuf.dsize) continue;
428 tl = Realloc(*list, sizeof(nt_forms_struct)*(n+1));
430 DEBUG(0,("get_ntforms: Realloc fail.\n"));
442 /****************************************************************************
443 write a form struct list
444 ****************************************************************************/
445 int write_ntforms(nt_forms_struct **list, int number)
452 for (i=0;i<number;i++) {
453 /* save index, so list is rebuilt in correct order */
454 len = tdb_pack(buf, sizeof(buf), "dddddddd",
455 i, (*list)[i].flag, (*list)[i].width, (*list)[i].length,
456 (*list)[i].left, (*list)[i].top, (*list)[i].right,
458 if (len > sizeof(buf)) break;
459 slprintf(key, sizeof(key)-1, "%s%s", FORMS_PREFIX, (*list)[i].name);
460 kbuf.dsize = strlen(key)+1;
464 if (tdb_store(tdb_forms, kbuf, dbuf, TDB_REPLACE) != 0) break;
470 /****************************************************************************
471 add a form struct at the end of the list
472 ****************************************************************************/
473 BOOL add_a_form(nt_forms_struct **list, const FORM *form, int *count)
481 * NT tries to add forms even when
482 * they are already in the base
483 * only update the values if already present
488 unistr2_to_ascii(form_name, &form->name, sizeof(form_name)-1);
489 for (n=0; n<*count; n++) {
490 if (!strncmp((*list)[n].name, form_name, strlen(form_name))) {
491 DEBUG(103, ("NT workaround, [%s] already exists\n", form_name));
498 if((tl=Realloc(*list, (n+1)*sizeof(nt_forms_struct))) == NULL) {
499 DEBUG(0,("add_a_form: failed to enlarge forms list!\n"));
503 unistr2_to_ascii((*list)[n].name, &form->name, sizeof((*list)[n].name)-1);
507 (*list)[n].flag=form->flags;
508 (*list)[n].width=form->size_x;
509 (*list)[n].length=form->size_y;
510 (*list)[n].left=form->left;
511 (*list)[n].top=form->top;
512 (*list)[n].right=form->right;
513 (*list)[n].bottom=form->bottom;
518 /****************************************************************************
519 delete a named form struct
520 ****************************************************************************/
521 BOOL delete_a_form(nt_forms_struct **list, UNISTR2 *del_name, int *count, WERROR *ret)
530 unistr2_to_ascii(form_name, del_name, sizeof(form_name)-1);
532 for (n=0; n<*count; n++) {
533 if (!strncmp((*list)[n].name, form_name, strlen(form_name))) {
534 DEBUG(103, ("delete_a_form, [%s] in list\n", form_name));
540 DEBUG(10,("delete_a_form, [%s] not found\n", form_name));
541 *ret = WERR_INVALID_PARAM;
545 slprintf(key, sizeof(key)-1, "%s%s", FORMS_PREFIX, (*list)[n].name);
546 kbuf.dsize = strlen(key)+1;
548 if (tdb_delete(tdb_forms, kbuf) != 0) {
556 /****************************************************************************
558 ****************************************************************************/
559 void update_a_form(nt_forms_struct **list, const FORM *form, int count)
563 unistr2_to_ascii(form_name, &(form->name), sizeof(form_name)-1);
565 DEBUG(106, ("[%s]\n", form_name));
566 for (n=0; n<count; n++)
568 DEBUGADD(106, ("n [%d]:[%s]\n", n, (*list)[n].name));
569 if (!strncmp((*list)[n].name, form_name, strlen(form_name)))
573 if (n==count) return;
575 (*list)[n].flag=form->flags;
576 (*list)[n].width=form->size_x;
577 (*list)[n].length=form->size_y;
578 (*list)[n].left=form->left;
579 (*list)[n].top=form->top;
580 (*list)[n].right=form->right;
581 (*list)[n].bottom=form->bottom;
584 /****************************************************************************
585 get the nt drivers list
587 traverse the database and look-up the matching names
588 ****************************************************************************/
589 int get_ntdrivers(fstring **list, char *architecture, uint32 version)
595 TDB_DATA kbuf, newkey;
597 get_short_archi(short_archi, architecture);
598 slprintf(key, sizeof(key)-1, "%s%s/%d/", DRIVERS_PREFIX, short_archi, version);
600 for (kbuf = tdb_firstkey(tdb_drivers);
602 newkey = tdb_nextkey(tdb_drivers, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
603 if (strncmp(kbuf.dptr, key, strlen(key)) != 0) continue;
605 if((fl = Realloc(*list, sizeof(fstring)*(total+1))) == NULL) {
606 DEBUG(0,("get_ntdrivers: failed to enlarge list!\n"));
611 fstrcpy((*list)[total], kbuf.dptr+strlen(key));
618 /****************************************************************************
619 function to do the mapping between the long architecture name and
621 ****************************************************************************/
622 BOOL get_short_archi(char *short_archi, char *long_archi)
629 struct table archi_table[]=
631 {"Windows 4.0", "WIN40" },
632 {"Windows NT x86", "W32X86" },
633 {"Windows NT R4000", "W32MIPS" },
634 {"Windows NT Alpha_AXP", "W32ALPHA" },
635 {"Windows NT PowerPC", "W32PPC" },
641 DEBUG(107,("Getting architecture dependant directory\n"));
644 } while ( (archi_table[i].long_archi!=NULL ) &&
645 StrCaseCmp(long_archi, archi_table[i].long_archi) );
647 if (archi_table[i].long_archi==NULL) {
648 DEBUGADD(107,("Unknown architecture [%s] !\n", long_archi));
652 StrnCpy (short_archi, archi_table[i].short_archi, strlen(archi_table[i].short_archi));
654 DEBUGADD(108,("index: [%d]\n", i));
655 DEBUGADD(108,("long architecture: [%s]\n", long_archi));
656 DEBUGADD(108,("short architecture: [%s]\n", short_archi));
661 /****************************************************************************
662 Version information in Microsoft files is held in a VS_VERSION_INFO structure.
663 There are two case to be covered here: PE (Portable Executable) and NE (New
664 Executable) files. Both files support the same INFO structure, but PE files
665 store the signature in unicode, and NE files store it as !unicode.
666 returns -1 on error, 1 on version info found, and 0 on no version info found.
667 ****************************************************************************/
669 static int get_file_version(files_struct *fsp, char *fname,uint32 *major, uint32 *minor)
675 if ((buf=malloc(PE_HEADER_SIZE)) == NULL) {
676 DEBUG(0,("get_file_version: PE file [%s] PE Header malloc failed bytes = %d\n",
677 fname, PE_HEADER_SIZE));
681 /* Note: DOS_HEADER_SIZE < malloc'ed PE_HEADER_SIZE */
682 if ((byte_count = vfs_read_data(fsp, buf, DOS_HEADER_SIZE)) < DOS_HEADER_SIZE) {
683 DEBUG(3,("get_file_version: File [%s] DOS header too short, bytes read = %d\n",
685 goto no_version_info;
688 /* Is this really a DOS header? */
689 if (SVAL(buf,DOS_HEADER_MAGIC_OFFSET) != DOS_HEADER_MAGIC) {
690 DEBUG(6,("get_file_version: File [%s] bad DOS magic = 0x%x\n",
691 fname, SVAL(buf,DOS_HEADER_MAGIC_OFFSET)));
692 goto no_version_info;
695 /* Skip OEM header (if any) and the DOS stub to start of Windows header */
696 if (fsp->conn->vfs_ops.lseek(fsp, fsp->fd, SVAL(buf,DOS_HEADER_LFANEW_OFFSET), SEEK_SET) == (SMB_OFF_T)-1) {
697 DEBUG(3,("get_file_version: File [%s] too short, errno = %d\n",
699 /* Assume this isn't an error... the file just looks sort of like a PE/NE file */
700 goto no_version_info;
703 if ((byte_count = vfs_read_data(fsp, buf, PE_HEADER_SIZE)) < PE_HEADER_SIZE) {
704 DEBUG(3,("get_file_version: File [%s] Windows header too short, bytes read = %d\n",
706 /* Assume this isn't an error... the file just looks sort of like a PE/NE file */
707 goto no_version_info;
710 /* The header may be a PE (Portable Executable) or an NE (New Executable) */
711 if (IVAL(buf,PE_HEADER_SIGNATURE_OFFSET) == PE_HEADER_SIGNATURE) {
713 int section_table_bytes;
715 if (SVAL(buf,PE_HEADER_MACHINE_OFFSET) != PE_HEADER_MACHINE_I386) {
716 DEBUG(3,("get_file_version: PE file [%s] wrong machine = 0x%x\n",
717 fname, SVAL(buf,PE_HEADER_MACHINE_OFFSET)));
718 /* At this point, we assume the file is in error. It still could be somthing
719 * else besides a PE file, but it unlikely at this point.
724 /* get the section table */
725 num_sections = SVAL(buf,PE_HEADER_NUMBER_OF_SECTIONS);
726 section_table_bytes = num_sections * PE_HEADER_SECT_HEADER_SIZE;
728 if ((buf=malloc(section_table_bytes)) == NULL) {
729 DEBUG(0,("get_file_version: PE file [%s] section table malloc failed bytes = %d\n",
730 fname, section_table_bytes));
734 if ((byte_count = vfs_read_data(fsp, buf, section_table_bytes)) < section_table_bytes) {
735 DEBUG(3,("get_file_version: PE file [%s] Section header too short, bytes read = %d\n",
740 /* Iterate the section table looking for the resource section ".rsrc" */
741 for (i = 0; i < num_sections; i++) {
742 int sec_offset = i * PE_HEADER_SECT_HEADER_SIZE;
744 if (strcmp(".rsrc", &buf[sec_offset+PE_HEADER_SECT_NAME_OFFSET]) == 0) {
745 int section_pos = IVAL(buf,sec_offset+PE_HEADER_SECT_PTR_DATA_OFFSET);
746 int section_bytes = IVAL(buf,sec_offset+PE_HEADER_SECT_SIZE_DATA_OFFSET);
749 if ((buf=malloc(section_bytes)) == NULL) {
750 DEBUG(0,("get_file_version: PE file [%s] version malloc failed bytes = %d\n",
751 fname, section_bytes));
755 /* Seek to the start of the .rsrc section info */
756 if (fsp->conn->vfs_ops.lseek(fsp, fsp->fd, section_pos, SEEK_SET) == (SMB_OFF_T)-1) {
757 DEBUG(3,("get_file_version: PE file [%s] too short for section info, errno = %d\n",
762 if ((byte_count = vfs_read_data(fsp, buf, section_bytes)) < section_bytes) {
763 DEBUG(3,("get_file_version: PE file [%s] .rsrc section too short, bytes read = %d\n",
768 for (i=0; i<section_bytes-VS_VERSION_INFO_UNICODE_SIZE; i++) {
769 /* Scan for 1st 3 unicoded bytes followed by word aligned magic value */
770 if (buf[i] == 'V' && buf[i+1] == '\0' && buf[i+2] == 'S') {
771 /* Align to next long address */
772 int pos = (i + sizeof(VS_SIGNATURE)*2 + 3) & 0xfffffffc;
774 if (IVAL(buf,pos) == VS_MAGIC_VALUE) {
775 *major = IVAL(buf,pos+VS_MAJOR_OFFSET);
776 *minor = IVAL(buf,pos+VS_MINOR_OFFSET);
778 DEBUG(6,("get_file_version: PE file [%s] Version = %08x:%08x (%d.%d.%d.%d)\n",
779 fname, *major, *minor,
780 (*major>>16)&0xffff, *major&0xffff,
781 (*minor>>16)&0xffff, *minor&0xffff));
790 /* Version info not found, fall back to origin date/time */
791 DEBUG(10,("get_file_version: PE file [%s] has no version info\n", fname));
795 } else if (SVAL(buf,NE_HEADER_SIGNATURE_OFFSET) == NE_HEADER_SIGNATURE) {
796 if (CVAL(buf,NE_HEADER_TARGET_OS_OFFSET) != NE_HEADER_TARGOS_WIN ) {
797 DEBUG(3,("get_file_version: NE file [%s] wrong target OS = 0x%x\n",
798 fname, CVAL(buf,NE_HEADER_TARGET_OS_OFFSET)));
799 /* At this point, we assume the file is in error. It still could be somthing
800 * else besides a NE file, but it unlikely at this point. */
804 /* Allocate a bit more space to speed up things */
806 if ((buf=malloc(VS_NE_BUF_SIZE)) == NULL) {
807 DEBUG(0,("get_file_version: NE file [%s] malloc failed bytes = %d\n",
808 fname, PE_HEADER_SIZE));
812 /* This is a HACK! I got tired of trying to sort through the messy
813 * 'NE' file format. If anyone wants to clean this up please have at
814 * it, but this works. 'NE' files will eventually fade away. JRR */
815 while((byte_count = vfs_read_data(fsp, buf, VS_NE_BUF_SIZE)) > 0) {
816 /* Cover case that should not occur in a well formed 'NE' .dll file */
817 if (byte_count-VS_VERSION_INFO_SIZE <= 0) break;
819 for(i=0; i<byte_count; i++) {
820 /* Fast skip past data that can't possibly match */
821 if (buf[i] != 'V') continue;
823 /* Potential match data crosses buf boundry, move it to beginning
824 * of buf, and fill the buf with as much as it will hold. */
825 if (i>byte_count-VS_VERSION_INFO_SIZE) {
828 memcpy(buf, &buf[i], byte_count-i);
829 if ((bc = vfs_read_data(fsp, &buf[byte_count-i], VS_NE_BUF_SIZE-
830 (byte_count-i))) < 0) {
832 DEBUG(0,("get_file_version: NE file [%s] Read error, errno=%d\n",
837 byte_count = bc + (byte_count - i);
838 if (byte_count<VS_VERSION_INFO_SIZE) break;
843 /* Check that the full signature string and the magic number that
844 * follows exist (not a perfect solution, but the chances that this
845 * occurs in code is, well, remote. Yes I know I'm comparing the 'V'
846 * twice, as it is simpler to read the code. */
847 if (strcmp(&buf[i], VS_SIGNATURE) == 0) {
848 /* Compute skip alignment to next long address */
849 int skip = -(fsp->conn->vfs_ops.lseek(fsp, fsp->fd, 0, SEEK_CUR) - (byte_count - i) +
850 sizeof(VS_SIGNATURE)) & 3;
851 if (IVAL(buf,i+sizeof(VS_SIGNATURE)+skip) != 0xfeef04bd) continue;
853 *major = IVAL(buf,i+sizeof(VS_SIGNATURE)+skip+VS_MAJOR_OFFSET);
854 *minor = IVAL(buf,i+sizeof(VS_SIGNATURE)+skip+VS_MINOR_OFFSET);
855 DEBUG(6,("get_file_version: NE file [%s] Version = %08x:%08x (%d.%d.%d.%d)\n",
856 fname, *major, *minor,
857 (*major>>16)&0xffff, *major&0xffff,
858 (*minor>>16)&0xffff, *minor&0xffff));
865 /* Version info not found, fall back to origin date/time */
866 DEBUG(0,("get_file_version: NE file [%s] Version info not found\n", fname));
871 /* Assume this isn't an error... the file just looks sort of like a PE/NE file */
872 DEBUG(3,("get_file_version: File [%s] unknown file format, signature = 0x%x\n",
873 fname, IVAL(buf,PE_HEADER_SIGNATURE_OFFSET)));
884 /****************************************************************************
885 Drivers for Microsoft systems contain multiple files. Often, multiple drivers
886 share one or more files. During the MS installation process files are checked
887 to insure that only a newer version of a shared file is installed over an
888 older version. There are several possibilities for this comparison. If there
889 is no previous version, the new one is newer (obviously). If either file is
890 missing the version info structure, compare the creation date (on Unix use
891 the modification date). Otherwise chose the numerically larger version number.
892 ****************************************************************************/
893 static int file_version_is_newer(connection_struct *conn, fstring new_file,
896 BOOL use_version = True;
901 time_t new_create_time;
905 time_t old_create_time;
909 files_struct *fsp = NULL;
911 SMB_STRUCT_STAT stat_buf;
915 ZERO_STRUCT(stat_buf);
916 new_create_time = (time_t)0;
917 old_create_time = (time_t)0;
919 /* Get file version info (if available) for previous file (if it exists) */
920 pstrcpy(filepath, old_file);
922 unix_convert(filepath,conn,NULL,&bad_path,&stat_buf);
924 fsp = open_file_shared(conn, filepath, &stat_buf,
925 SET_OPEN_MODE(DOS_OPEN_RDONLY),
926 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
927 0, 0, &access_mode, &action);
929 /* Old file not found, so by definition new file is in fact newer */
930 DEBUG(10,("file_version_is_newer: Can't open old file [%s], errno = %d\n",
935 int ret = get_file_version(fsp, old_file, &old_major, &old_minor);
936 if (ret == -1) goto error_exit;
939 DEBUG(6,("file_version_is_newer: Version info not found [%s], use mod time\n",
942 if (fsp->conn->vfs_ops.fstat(fsp, fsp->fd, &st) == -1) goto error_exit;
943 old_create_time = st.st_mtime;
944 DEBUGADD(6,("file_version_is_newer: mod time = %ld sec\n", old_create_time));
947 close_file(fsp, True);
949 /* Get file version info (if available) for new file */
950 pstrcpy(filepath, new_file);
951 unix_convert(filepath,conn,NULL,&bad_path,&stat_buf);
953 fsp = open_file_shared(conn, filepath, &stat_buf,
954 SET_OPEN_MODE(DOS_OPEN_RDONLY),
955 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
956 0, 0, &access_mode, &action);
958 /* New file not found, this shouldn't occur if the caller did its job */
959 DEBUG(3,("file_version_is_newer: Can't open new file [%s], errno = %d\n",
964 int ret = get_file_version(fsp, new_file, &new_major, &new_minor);
965 if (ret == -1) goto error_exit;
968 DEBUG(6,("file_version_is_newer: Version info not found [%s], use mod time\n",
971 if (fsp->conn->vfs_ops.fstat(fsp, fsp->fd, &st) == -1) goto error_exit;
972 new_create_time = st.st_mtime;
973 DEBUGADD(6,("file_version_is_newer: mod time = %ld sec\n", new_create_time));
976 close_file(fsp, True);
979 /* Compare versions and choose the larger version number */
980 if (new_major > old_major ||
981 (new_major == old_major && new_minor > old_minor)) {
983 DEBUG(6,("file_version_is_newer: Replacing [%s] with [%s]\n", old_file, new_file));
987 DEBUG(6,("file_version_is_newer: Leaving [%s] unchanged\n", old_file));
992 /* Compare modification time/dates and choose the newest time/date */
993 if (new_create_time > old_create_time) {
994 DEBUG(6,("file_version_is_newer: Replacing [%s] with [%s]\n", old_file, new_file));
998 DEBUG(6,("file_version_is_newer: Leaving [%s] unchanged\n", old_file));
1005 close_file(fsp, True);
1009 /****************************************************************************
1010 Determine the correct cVersion associated with an architecture and driver
1011 ****************************************************************************/
1012 static uint32 get_correct_cversion(fstring architecture, fstring driverpath_in,
1013 struct current_user *user, WERROR *perr)
1021 files_struct *fsp = NULL;
1024 connection_struct *conn;
1028 *perr = WERR_INVALID_PARAM;
1030 /* If architecture is Windows 95/98/ME, the version is always 0. */
1031 if (strcmp(architecture, "WIN40") == 0) {
1032 DEBUG(10,("get_correct_cversion: Driver is Win9x, cversion = 0\n"));
1038 * Connect to the print$ share under the same account as the user connected
1039 * to the rpc pipe. Note we must still be root to do this.
1042 /* Null password is ok - we are already an authenticated user... */
1043 null_pw = data_blob(NULL, 0);
1045 conn = make_connection("print$", null_pw, "A:", user->vuid, &nt_status);
1049 DEBUG(0,("get_correct_cversion: Unable to connect\n"));
1050 *perr = ntstatus_to_werror(nt_status);
1054 /* We are temporarily becoming the connection user. */
1055 if (!become_user(conn, conn->vuid)) {
1056 DEBUG(0,("get_correct_cversion: Can't become user!\n"));
1057 *perr = WERR_ACCESS_DENIED;
1061 /* Open the driver file (Portable Executable format) and determine the
1062 * deriver the cversion. */
1063 slprintf(driverpath, sizeof(driverpath)-1, "%s/%s", architecture, driverpath_in);
1065 unix_convert(driverpath,conn,NULL,&bad_path,&st);
1067 fsp = open_file_shared(conn, driverpath, &st,
1068 SET_OPEN_MODE(DOS_OPEN_RDONLY),
1069 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
1070 0, 0, &access_mode, &action);
1072 DEBUG(3,("get_correct_cversion: Can't open file [%s], errno = %d\n",
1073 driverpath, errno));
1074 *perr = WERR_ACCESS_DENIED;
1080 int ret = get_file_version(fsp, driverpath, &major, &minor);
1081 if (ret == -1) goto error_exit;
1084 DEBUG(6,("get_correct_cversion: Version info not found [%s]\n", driverpath));
1089 * This is a Microsoft'ism. See references in MSDN to VER_FILEVERSION
1090 * for more details. Version in this case is not just the version of the
1091 * file, but the version in the sense of kernal mode (2) vs. user mode
1092 * (3) drivers. Other bits of the version fields are the version info.
1095 cversion = major & 0x0000ffff;
1097 case 2: /* WinNT drivers */
1098 case 3: /* Win2K drivers */
1102 DEBUG(6,("get_correct_cversion: cversion invalid [%s] cversion = %d\n",
1103 driverpath, cversion));
1107 DEBUG(10,("get_correct_cversion: Version info found [%s] major = 0x%x minor = 0x%x\n",
1108 driverpath, major, minor));
1111 DEBUG(10,("get_correct_cversion: Driver file [%s] cversion = %d\n",
1112 driverpath, cversion));
1114 close_file(fsp, True);
1115 close_cnum(conn, user->vuid);
1124 close_file(fsp, True);
1126 close_cnum(conn, user->vuid);
1131 /****************************************************************************
1132 ****************************************************************************/
1133 static WERROR clean_up_driver_struct_level_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver,
1134 struct current_user *user)
1136 fstring architecture;
1142 /* clean up the driver name.
1143 * we can get .\driver.dll
1144 * or worse c:\windows\system\driver.dll !
1146 /* using an intermediate string to not have overlaping memcpy()'s */
1147 if ((p = strrchr(driver->driverpath,'\\')) != NULL) {
1148 fstrcpy(new_name, p+1);
1149 fstrcpy(driver->driverpath, new_name);
1152 if ((p = strrchr(driver->datafile,'\\')) != NULL) {
1153 fstrcpy(new_name, p+1);
1154 fstrcpy(driver->datafile, new_name);
1157 if ((p = strrchr(driver->configfile,'\\')) != NULL) {
1158 fstrcpy(new_name, p+1);
1159 fstrcpy(driver->configfile, new_name);
1162 if ((p = strrchr(driver->helpfile,'\\')) != NULL) {
1163 fstrcpy(new_name, p+1);
1164 fstrcpy(driver->helpfile, new_name);
1167 if (driver->dependentfiles) {
1168 for (i=0; *driver->dependentfiles[i]; i++) {
1169 if ((p = strrchr(driver->dependentfiles[i],'\\')) != NULL) {
1170 fstrcpy(new_name, p+1);
1171 fstrcpy(driver->dependentfiles[i], new_name);
1176 get_short_archi(architecture, driver->environment);
1178 /* jfm:7/16/2000 the client always sends the cversion=0.
1179 * The server should check which version the driver is by reading
1180 * the PE header of driver->driverpath.
1182 * For Windows 95/98 the version is 0 (so the value sent is correct)
1183 * For Windows NT (the architecture doesn't matter)
1184 * NT 3.1: cversion=0
1185 * NT 3.5/3.51: cversion=1
1189 if ((driver->cversion = get_correct_cversion( architecture,
1190 driver->driverpath, user, &err)) == -1)
1196 /****************************************************************************
1197 ****************************************************************************/
1198 static WERROR clean_up_driver_struct_level_6(NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver,
1199 struct current_user *user)
1201 fstring architecture;
1207 /* clean up the driver name.
1208 * we can get .\driver.dll
1209 * or worse c:\windows\system\driver.dll !
1211 /* using an intermediate string to not have overlaping memcpy()'s */
1212 if ((p = strrchr(driver->driverpath,'\\')) != NULL) {
1213 fstrcpy(new_name, p+1);
1214 fstrcpy(driver->driverpath, new_name);
1217 if ((p = strrchr(driver->datafile,'\\')) != NULL) {
1218 fstrcpy(new_name, p+1);
1219 fstrcpy(driver->datafile, new_name);
1222 if ((p = strrchr(driver->configfile,'\\')) != NULL) {
1223 fstrcpy(new_name, p+1);
1224 fstrcpy(driver->configfile, new_name);
1227 if ((p = strrchr(driver->helpfile,'\\')) != NULL) {
1228 fstrcpy(new_name, p+1);
1229 fstrcpy(driver->helpfile, new_name);
1232 if (driver->dependentfiles) {
1233 for (i=0; *driver->dependentfiles[i]; i++) {
1234 if ((p = strrchr(driver->dependentfiles[i],'\\')) != NULL) {
1235 fstrcpy(new_name, p+1);
1236 fstrcpy(driver->dependentfiles[i], new_name);
1241 get_short_archi(architecture, driver->environment);
1243 /* jfm:7/16/2000 the client always sends the cversion=0.
1244 * The server should check which version the driver is by reading
1245 * the PE header of driver->driverpath.
1247 * For Windows 95/98 the version is 0 (so the value sent is correct)
1248 * For Windows NT (the architecture doesn't matter)
1249 * NT 3.1: cversion=0
1250 * NT 3.5/3.51: cversion=1
1254 if ((driver->version = get_correct_cversion(architecture,
1255 driver->driverpath, user, &err)) == -1)
1261 /****************************************************************************
1262 ****************************************************************************/
1263 WERROR clean_up_driver_struct(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract,
1264 uint32 level, struct current_user *user)
1269 NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver;
1270 driver=driver_abstract.info_3;
1271 return clean_up_driver_struct_level_3(driver, user);
1275 NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver;
1276 driver=driver_abstract.info_6;
1277 return clean_up_driver_struct_level_6(driver, user);
1280 return WERR_INVALID_PARAM;
1284 /****************************************************************************
1285 This function sucks and should be replaced. JRA.
1286 ****************************************************************************/
1288 static void convert_level_6_to_level3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *dst, NT_PRINTER_DRIVER_INFO_LEVEL_6 *src)
1290 dst->cversion = src->version;
1292 fstrcpy( dst->name, src->name);
1293 fstrcpy( dst->environment, src->environment);
1294 fstrcpy( dst->driverpath, src->driverpath);
1295 fstrcpy( dst->datafile, src->datafile);
1296 fstrcpy( dst->configfile, src->configfile);
1297 fstrcpy( dst->helpfile, src->helpfile);
1298 fstrcpy( dst->monitorname, src->monitorname);
1299 fstrcpy( dst->defaultdatatype, src->defaultdatatype);
1300 dst->dependentfiles = src->dependentfiles;
1303 #if 0 /* Debugging function */
1305 static char* ffmt(unsigned char *c){
1307 static char ffmt_str[17];
1309 for (i=0; i<16; i++) {
1310 if ((c[i] < ' ') || (c[i] > '~'))
1321 /****************************************************************************
1322 ****************************************************************************/
1323 BOOL move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract, uint32 level,
1324 struct current_user *user, WERROR *perr)
1326 NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver;
1327 NT_PRINTER_DRIVER_INFO_LEVEL_3 converted_driver;
1328 fstring architecture;
1333 connection_struct *conn;
1340 memset(inbuf, '\0', sizeof(inbuf));
1341 memset(outbuf, '\0', sizeof(outbuf));
1345 driver=driver_abstract.info_3;
1346 else if (level==6) {
1347 convert_level_6_to_level3(&converted_driver, driver_abstract.info_6);
1348 driver = &converted_driver;
1350 DEBUG(0,("move_driver_to_download_area: Unknown info level (%u)\n", (unsigned int)level ));
1354 get_short_archi(architecture, driver->environment);
1357 * Connect to the print$ share under the same account as the user connected to the rpc pipe.
1358 * Note we must be root to do this.
1362 null_pw = data_blob(NULL, 0);
1363 conn = make_connection("print$", null_pw, "A:", user->vuid, &nt_status);
1367 DEBUG(0,("move_driver_to_download_area: Unable to connect\n"));
1368 *perr = ntstatus_to_werror(nt_status);
1373 * Save who we are - we are temporarily becoming the connection user.
1376 if (!become_user(conn, conn->vuid)) {
1377 DEBUG(0,("move_driver_to_download_area: Can't become user!\n"));
1382 * make the directories version and version\driver_name
1383 * under the architecture directory.
1385 DEBUG(5,("Creating first directory\n"));
1386 slprintf(new_dir, sizeof(new_dir)-1, "%s/%d", architecture, driver->cversion);
1387 mkdir_internal(conn, new_dir);
1389 /* For each driver file, archi\filexxx.yyy, if there is a duplicate file
1390 * listed for this driver which has already been moved, skip it (note:
1391 * drivers may list the same file name several times. Then check if the
1392 * file already exists in archi\cversion\, if so, check that the version
1393 * info (or time stamps if version info is unavailable) is newer (or the
1394 * date is later). If it is, move it to archi\cversion\filexxx.yyy.
1395 * Otherwise, delete the file.
1397 * If a file is not moved to archi\cversion\ because of an error, all the
1398 * rest of the 'unmoved' driver files are removed from archi\. If one or
1399 * more of the driver's files was already moved to archi\cversion\, it
1400 * potentially leaves the driver in a partially updated state. Version
1401 * trauma will most likely occur if an client attempts to use any printer
1402 * bound to the driver. Perhaps a rewrite to make sure the moves can be
1403 * done is appropriate... later JRR
1406 DEBUG(5,("Moving files now !\n"));
1408 if (driver->driverpath && strlen(driver->driverpath)) {
1409 slprintf(new_name, sizeof(new_name)-1, "%s/%s", architecture, driver->driverpath);
1410 slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->driverpath);
1411 if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
1413 status = rename_internals(conn, new_name, old_name, True);
1414 if (!NT_STATUS_IS_OK(status)) {
1415 DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
1416 new_name, old_name));
1417 *perr = ntstatus_to_werror(status);
1418 unlink_internals(conn, 0, new_name);
1423 unlink_internals(conn, 0, new_name);
1426 if (driver->datafile && strlen(driver->datafile)) {
1427 if (!strequal(driver->datafile, driver->driverpath)) {
1428 slprintf(new_name, sizeof(new_name)-1, "%s/%s", architecture, driver->datafile);
1429 slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->datafile);
1430 if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
1432 status = rename_internals(conn, new_name, old_name, True);
1433 if (!NT_STATUS_IS_OK(status)) {
1434 DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
1435 new_name, old_name));
1436 *perr = ntstatus_to_werror(status);
1437 unlink_internals(conn, 0, new_name);
1442 unlink_internals(conn, 0, new_name);
1446 if (driver->configfile && strlen(driver->configfile)) {
1447 if (!strequal(driver->configfile, driver->driverpath) &&
1448 !strequal(driver->configfile, driver->datafile)) {
1449 slprintf(new_name, sizeof(new_name)-1, "%s/%s", architecture, driver->configfile);
1450 slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->configfile);
1451 if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
1453 status = rename_internals(conn, new_name, old_name, True);
1454 if (!NT_STATUS_IS_OK(status)) {
1455 DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
1456 new_name, old_name));
1457 *perr = ntstatus_to_werror(status);
1458 unlink_internals(conn, 0, new_name);
1463 unlink_internals(conn, 0, new_name);
1467 if (driver->helpfile && strlen(driver->helpfile)) {
1468 if (!strequal(driver->helpfile, driver->driverpath) &&
1469 !strequal(driver->helpfile, driver->datafile) &&
1470 !strequal(driver->helpfile, driver->configfile)) {
1471 slprintf(new_name, sizeof(new_name)-1, "%s/%s", architecture, driver->helpfile);
1472 slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->helpfile);
1473 if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
1475 status = rename_internals(conn, new_name, old_name, True);
1476 if (!NT_STATUS_IS_OK(status)) {
1477 DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
1478 new_name, old_name));
1479 *perr = ntstatus_to_werror(status);
1480 unlink_internals(conn, 0, new_name);
1485 unlink_internals(conn, 0, new_name);
1489 if (driver->dependentfiles) {
1490 for (i=0; *driver->dependentfiles[i]; i++) {
1491 if (!strequal(driver->dependentfiles[i], driver->driverpath) &&
1492 !strequal(driver->dependentfiles[i], driver->datafile) &&
1493 !strequal(driver->dependentfiles[i], driver->configfile) &&
1494 !strequal(driver->dependentfiles[i], driver->helpfile)) {
1496 for (j=0; j < i; j++) {
1497 if (strequal(driver->dependentfiles[i], driver->dependentfiles[j])) {
1502 slprintf(new_name, sizeof(new_name)-1, "%s/%s", architecture, driver->dependentfiles[i]);
1503 slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->dependentfiles[i]);
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);
1522 close_cnum(conn, user->vuid);
1525 return ver == -1 ? False : True;
1528 /****************************************************************************
1529 ****************************************************************************/
1530 static uint32 add_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver)
1533 fstring architecture;
1539 TDB_DATA kbuf, dbuf;
1541 get_short_archi(architecture, driver->environment);
1543 /* The names are relative. We store them in the form: \print$\arch\version\driver.xxx
1544 * \\server is added in the rpc server layer.
1545 * It does make sense to NOT store the server's name in the printer TDB.
1548 slprintf(directory, sizeof(directory)-1, "\\print$\\%s\\%d\\", architecture, driver->cversion);
1550 /* .inf files do not always list a file for each of the four standard files.
1551 * Don't prepend a path to a null filename, or client claims:
1552 * "The server on which the printer resides does not have a suitable
1553 * <printer driver name> printer driver installed. Click OK if you
1554 * wish to install the driver on your local machine."
1556 if (strlen(driver->driverpath)) {
1557 fstrcpy(temp_name, driver->driverpath);
1558 slprintf(driver->driverpath, sizeof(driver->driverpath)-1, "%s%s", directory, temp_name);
1561 if (strlen(driver->datafile)) {
1562 fstrcpy(temp_name, driver->datafile);
1563 slprintf(driver->datafile, sizeof(driver->datafile)-1, "%s%s", directory, temp_name);
1566 if (strlen(driver->configfile)) {
1567 fstrcpy(temp_name, driver->configfile);
1568 slprintf(driver->configfile, sizeof(driver->configfile)-1, "%s%s", directory, temp_name);
1571 if (strlen(driver->helpfile)) {
1572 fstrcpy(temp_name, driver->helpfile);
1573 slprintf(driver->helpfile, sizeof(driver->helpfile)-1, "%s%s", directory, temp_name);
1576 if (driver->dependentfiles) {
1577 for (i=0; *driver->dependentfiles[i]; i++) {
1578 fstrcpy(temp_name, driver->dependentfiles[i]);
1579 slprintf(driver->dependentfiles[i], sizeof(driver->dependentfiles[i])-1, "%s%s", directory, temp_name);
1583 slprintf(key, sizeof(key)-1, "%s%s/%d/%s", DRIVERS_PREFIX, architecture, driver->cversion, driver->name);
1585 DEBUG(5,("add_a_printer_driver_3: Adding driver with key %s\n", key ));
1592 len += tdb_pack(buf+len, buflen-len, "dffffffff",
1595 driver->environment,
1600 driver->monitorname,
1601 driver->defaultdatatype);
1603 if (driver->dependentfiles) {
1604 for (i=0; *driver->dependentfiles[i]; i++) {
1605 len += tdb_pack(buf+len, buflen-len, "f",
1606 driver->dependentfiles[i]);
1610 if (len != buflen) {
1613 tb = (char *)Realloc(buf, len);
1615 DEBUG(0,("add_a_printer_driver_3: failed to enlarge buffer\n!"));
1626 kbuf.dsize = strlen(key)+1;
1630 ret = tdb_store(tdb_drivers, kbuf, dbuf, TDB_REPLACE);
1634 DEBUG(0,("add_a_printer_driver_3: Adding driver with key %s failed.\n", key ));
1640 /****************************************************************************
1641 ****************************************************************************/
1642 static uint32 add_a_printer_driver_6(NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver)
1644 NT_PRINTER_DRIVER_INFO_LEVEL_3 info3;
1647 info3.cversion = driver->version;
1648 fstrcpy(info3.name,driver->name);
1649 fstrcpy(info3.environment,driver->environment);
1650 fstrcpy(info3.driverpath,driver->driverpath);
1651 fstrcpy(info3.datafile,driver->datafile);
1652 fstrcpy(info3.configfile,driver->configfile);
1653 fstrcpy(info3.helpfile,driver->helpfile);
1654 fstrcpy(info3.monitorname,driver->monitorname);
1655 fstrcpy(info3.defaultdatatype,driver->defaultdatatype);
1656 info3.dependentfiles = driver->dependentfiles;
1658 return add_a_printer_driver_3(&info3);
1662 /****************************************************************************
1663 ****************************************************************************/
1664 static WERROR get_a_printer_driver_3_default(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, fstring in_prt, fstring in_arch)
1666 NT_PRINTER_DRIVER_INFO_LEVEL_3 info;
1670 fstrcpy(info.name, in_prt);
1671 fstrcpy(info.defaultdatatype, "RAW");
1673 fstrcpy(info.driverpath, "");
1674 fstrcpy(info.datafile, "");
1675 fstrcpy(info.configfile, "");
1676 fstrcpy(info.helpfile, "");
1678 if ((info.dependentfiles=(fstring *)malloc(2*sizeof(fstring))) == NULL)
1681 memset(info.dependentfiles, '\0', 2*sizeof(fstring));
1682 fstrcpy(info.dependentfiles[0], "");
1684 *info_ptr = memdup(&info, sizeof(info));
1689 /****************************************************************************
1690 ****************************************************************************/
1691 static WERROR get_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, fstring in_prt, fstring in_arch, uint32 version)
1693 NT_PRINTER_DRIVER_INFO_LEVEL_3 driver;
1694 TDB_DATA kbuf, dbuf;
1695 fstring architecture;
1700 ZERO_STRUCT(driver);
1702 get_short_archi(architecture, in_arch);
1704 DEBUG(8,("get_a_printer_driver_3: [%s%s/%d/%s]\n", DRIVERS_PREFIX, architecture, version, in_prt));
1706 slprintf(key, sizeof(key)-1, "%s%s/%d/%s", DRIVERS_PREFIX, architecture, version, in_prt);
1709 kbuf.dsize = strlen(key)+1;
1711 dbuf = tdb_fetch(tdb_drivers, kbuf);
1713 if (!dbuf.dptr) return get_a_printer_driver_3_default(info_ptr, in_prt, in_arch);
1715 if (!dbuf.dptr) return WERR_ACCESS_DENIED;
1717 len += tdb_unpack(dbuf.dptr, dbuf.dsize, "dffffffff",
1726 driver.defaultdatatype);
1729 while (len < dbuf.dsize) {
1732 tddfs = (fstring *)Realloc(driver.dependentfiles,
1733 sizeof(fstring)*(i+2));
1734 if (tddfs == NULL) {
1735 DEBUG(0,("get_a_printer_driver_3: failed to enlarge buffer!\n"));
1738 else driver.dependentfiles = tddfs;
1740 len += tdb_unpack(dbuf.dptr+len, dbuf.dsize-len, "f",
1741 &driver.dependentfiles[i]);
1744 if (driver.dependentfiles != NULL)
1745 fstrcpy(driver.dependentfiles[i], "");
1747 SAFE_FREE(dbuf.dptr);
1749 if (len != dbuf.dsize) {
1750 SAFE_FREE(driver.dependentfiles);
1752 return get_a_printer_driver_3_default(info_ptr, in_prt, in_arch);
1755 *info_ptr = (NT_PRINTER_DRIVER_INFO_LEVEL_3 *)memdup(&driver, sizeof(driver));
1760 /****************************************************************************
1761 ****************************************************************************/
1762 uint32 get_a_printer_driver_9x_compatible(pstring line, fstring model)
1764 NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3;
1770 slprintf(key, sizeof(key)-1, "%s%s/%d/%s", DRIVERS_PREFIX, "WIN40", 0, model);
1771 DEBUG(10,("driver key: [%s]\n", key));
1774 kbuf.dsize = strlen(key)+1;
1775 if (!tdb_exists(tdb_drivers, kbuf))
1779 get_a_printer_driver_3(&info3, model, "Windows 4.0", 0);
1781 DEBUGADD(10,("info3->name [%s]\n", info3->name));
1782 DEBUGADD(10,("info3->datafile [%s]\n", info3->datafile));
1783 DEBUGADD(10,("info3->helpfile [%s]\n", info3->helpfile));
1784 DEBUGADD(10,("info3->monitorname [%s]\n", info3->monitorname));
1785 DEBUGADD(10,("info3->defaultdatatype [%s]\n", info3->defaultdatatype));
1786 for (i=0; info3->dependentfiles && *info3->dependentfiles[i]; i++) {
1787 DEBUGADD(10,("info3->dependentfiles [%s]\n", info3->dependentfiles[i]));
1789 DEBUGADD(10,("info3->environment [%s]\n", info3->environment));
1790 DEBUGADD(10,("info3->driverpath [%s]\n", info3->driverpath));
1791 DEBUGADD(10,("info3->configfile [%s]\n", info3->configfile));
1793 /*pstrcat(line, info3->name); pstrcat(line, ":");*/
1794 trim_string(info3->driverpath, "\\print$\\WIN40\\0\\", 0);
1795 pstrcat(line, info3->driverpath);
1797 trim_string(info3->datafile, "\\print$\\WIN40\\0\\", 0);
1798 pstrcat(line, info3->datafile);
1800 trim_string(info3->helpfile, "\\print$\\WIN40\\0\\", 0);
1801 pstrcat(line, info3->helpfile);
1803 trim_string(info3->monitorname, "\\print$\\WIN40\\0\\", 0);
1804 pstrcat(line, info3->monitorname);
1806 pstrcat(line, "RAW"); /*info3->defaultdatatype);*/
1809 for (i=0; info3->dependentfiles && *info3->dependentfiles[i]; i++) {
1811 pstrcat(line, ","); /* don't end in a "," */
1812 trim_string(info3->dependentfiles[i], "\\print$\\WIN40\\0\\", 0);
1813 pstrcat(line, info3->dependentfiles[i]);
1821 /****************************************************************************
1822 Debugging function, dump at level 6 the struct in the logs.
1823 ****************************************************************************/
1825 static uint32 dump_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
1828 NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3;
1831 DEBUG(106,("Dumping printer driver at level [%d]\n", level));
1837 if (driver.info_3 == NULL)
1840 info3=driver.info_3;
1842 DEBUGADD(106,("version:[%d]\n", info3->cversion));
1843 DEBUGADD(106,("name:[%s]\n", info3->name));
1844 DEBUGADD(106,("environment:[%s]\n", info3->environment));
1845 DEBUGADD(106,("driverpath:[%s]\n", info3->driverpath));
1846 DEBUGADD(106,("datafile:[%s]\n", info3->datafile));
1847 DEBUGADD(106,("configfile:[%s]\n", info3->configfile));
1848 DEBUGADD(106,("helpfile:[%s]\n", info3->helpfile));
1849 DEBUGADD(106,("monitorname:[%s]\n", info3->monitorname));
1850 DEBUGADD(106,("defaultdatatype:[%s]\n", info3->defaultdatatype));
1852 for (i=0; info3->dependentfiles &&
1853 *info3->dependentfiles[i]; i++) {
1854 DEBUGADD(106,("dependentfile:[%s]\n",
1855 info3->dependentfiles[i]));
1862 DEBUGADD(106,("dump_a_printer_driver: Level %u not implemented\n", (unsigned int)level));
1870 /****************************************************************************
1871 ****************************************************************************/
1872 static int pack_devicemode(NT_DEVICEMODE *nt_devmode, char *buf, int buflen)
1876 len += tdb_pack(buf+len, buflen-len, "p", nt_devmode);
1878 if (!nt_devmode) return len;
1880 len += tdb_pack(buf+len, buflen-len, "ffwwwwwwwwwwwwwwwwwwddddddddddddddp",
1881 nt_devmode->devicename,
1882 nt_devmode->formname,
1884 nt_devmode->specversion,
1885 nt_devmode->driverversion,
1887 nt_devmode->driverextra,
1888 nt_devmode->orientation,
1889 nt_devmode->papersize,
1890 nt_devmode->paperlength,
1891 nt_devmode->paperwidth,
1894 nt_devmode->defaultsource,
1895 nt_devmode->printquality,
1898 nt_devmode->yresolution,
1899 nt_devmode->ttoption,
1900 nt_devmode->collate,
1901 nt_devmode->logpixels,
1904 nt_devmode->bitsperpel,
1905 nt_devmode->pelswidth,
1906 nt_devmode->pelsheight,
1907 nt_devmode->displayflags,
1908 nt_devmode->displayfrequency,
1909 nt_devmode->icmmethod,
1910 nt_devmode->icmintent,
1911 nt_devmode->mediatype,
1912 nt_devmode->dithertype,
1913 nt_devmode->reserved1,
1914 nt_devmode->reserved2,
1915 nt_devmode->panningwidth,
1916 nt_devmode->panningheight,
1917 nt_devmode->private);
1920 if (nt_devmode->private) {
1921 len += tdb_pack(buf+len, buflen-len, "B",
1922 nt_devmode->driverextra,
1923 nt_devmode->private);
1926 DEBUG(8,("Packed devicemode [%s]\n", nt_devmode->formname));
1931 /****************************************************************************
1932 ****************************************************************************/
1933 static int pack_specifics(NT_PRINTER_PARAM *param, char *buf, int buflen)
1937 while (param != NULL) {
1938 len += tdb_pack(buf+len, buflen-len, "pfdB",
1947 len += tdb_pack(buf+len, buflen-len, "p", param);
1953 /****************************************************************************
1954 Delete a printer - this just deletes the printer info file, any open
1955 handles are not affected.
1956 ****************************************************************************/
1958 uint32 del_a_printer(char *sharename)
1963 slprintf(key, sizeof(key)-1, "%s%s", PRINTERS_PREFIX, sharename);
1966 kbuf.dsize=strlen(key)+1;
1968 tdb_delete(tdb_printers, kbuf);
1972 /* FIXME!!! Reorder so this forward declaration is not necessary --jerry */
1973 static WERROR get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **, fstring);
1974 static void free_nt_printer_info_level_2(NT_PRINTER_INFO_LEVEL_2 **);
1975 /****************************************************************************
1976 ****************************************************************************/
1977 static WERROR update_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info)
1983 TDB_DATA kbuf, dbuf;
1986 * in addprinter: no servername and the printer is the name
1987 * in setprinter: servername is \\server
1988 * and printer is \\server\\printer
1990 * Samba manages only local printers.
1991 * we currently don't support things like path=\\other_server\printer
1994 if (info->servername[0]!='\0') {
1995 trim_string(info->printername, info->servername, NULL);
1996 trim_string(info->printername, "\\", NULL);
1997 info->servername[0]='\0';
2001 * JFM: one day I'll forget.
2002 * below that's info->portname because that's the SAMBA sharename
2003 * and I made NT 'thinks' it's the portname
2004 * the info->sharename is the thing you can name when you add a printer
2005 * that's the short-name when you create shared printer for 95/98
2006 * So I've made a limitation in SAMBA: you can only have 1 printer model
2007 * behind a SAMBA share.
2015 len += tdb_pack(buf+len, buflen-len, "dddddddddddfffffPfffff",
2018 info->default_priority,
2035 info->printprocessor,
2039 len += pack_devicemode(info->devmode, buf+len, buflen-len);
2041 len += pack_specifics(info->specific, buf+len, buflen-len);
2043 if (buflen != len) {
2046 tb = (char *)Realloc(buf, len);
2048 DEBUG(0,("update_a_printer_2: failed to enlarge buffer!\n"));
2058 slprintf(key, sizeof(key)-1, "%s%s", PRINTERS_PREFIX, info->sharename);
2061 kbuf.dsize = strlen(key)+1;
2065 ret = (tdb_store(tdb_printers, kbuf, dbuf, TDB_REPLACE) == 0? WERR_OK : WERR_NOMEM);
2068 if (!W_ERROR_IS_OK(ret))
2069 DEBUG(8, ("error updating printer to tdb on disk\n"));
2073 DEBUG(8,("packed printer [%s] with driver [%s] portname=[%s] len=%d\n",
2074 info->sharename, info->drivername, info->portname, len));
2080 /****************************************************************************
2081 ****************************************************************************/
2082 void add_a_specific_param(NT_PRINTER_INFO_LEVEL_2 *info_2, NT_PRINTER_PARAM **param)
2084 NT_PRINTER_PARAM *current;
2086 DEBUG(108,("add_a_specific_param\n"));
2088 (*param)->next=NULL;
2090 if (info_2->specific == NULL)
2092 info_2->specific=*param;
2096 current=info_2->specific;
2097 while (current->next != NULL) {
2098 current=current->next;
2100 current->next=*param;
2106 /****************************************************************************
2107 ****************************************************************************/
2108 BOOL unlink_specific_param_if_exist(NT_PRINTER_INFO_LEVEL_2 *info_2, NT_PRINTER_PARAM *param)
2110 NT_PRINTER_PARAM *current;
2111 NT_PRINTER_PARAM *previous;
2113 current=info_2->specific;
2116 if (current==NULL) return (False);
2118 if ( !strcmp(current->value, param->value) &&
2119 (strlen(current->value)==strlen(param->value)) ) {
2120 DEBUG(109,("deleting first value\n"));
2121 info_2->specific=current->next;
2122 SAFE_FREE(current->data);
2124 DEBUG(109,("deleted first value\n"));
2128 current=previous->next;
2130 while ( current!=NULL ) {
2131 if (!strcmp(current->value, param->value) &&
2132 strlen(current->value)==strlen(param->value) ) {
2133 DEBUG(109,("deleting current value\n"));
2134 previous->next=current->next;
2135 SAFE_FREE(current->data);
2137 DEBUG(109,("deleted current value\n"));
2141 previous=previous->next;
2142 current=current->next;
2147 /****************************************************************************
2148 Clean up and deallocate a (maybe partially) allocated NT_PRINTER_PARAM.
2149 ****************************************************************************/
2150 void free_nt_printer_param(NT_PRINTER_PARAM **param_ptr)
2152 NT_PRINTER_PARAM *param = *param_ptr;
2157 DEBUG(106,("free_nt_printer_param: deleting param [%s]\n", param->value));
2159 SAFE_FREE(param->data);
2160 SAFE_FREE(*param_ptr);
2163 /****************************************************************************
2164 Malloc and return an NT devicemode.
2165 ****************************************************************************/
2167 NT_DEVICEMODE *construct_nt_devicemode(const fstring default_devicename)
2171 NT_DEVICEMODE *nt_devmode = (NT_DEVICEMODE *)malloc(sizeof(NT_DEVICEMODE));
2173 if (nt_devmode == NULL) {
2174 DEBUG(0,("construct_nt_devicemode: malloc fail.\n"));
2178 ZERO_STRUCTP(nt_devmode);
2180 safe_strcpy(adevice, default_devicename, sizeof(adevice));
2181 fstrcpy(nt_devmode->devicename, adevice);
2183 fstrcpy(nt_devmode->formname, "Letter");
2185 nt_devmode->specversion = 0x0401;
2186 nt_devmode->driverversion = 0x0400;
2187 nt_devmode->size = 0x00DC;
2188 nt_devmode->driverextra = 0x0000;
2189 nt_devmode->fields = FORMNAME | TTOPTION | PRINTQUALITY |
2190 DEFAULTSOURCE | COPIES | SCALE |
2191 PAPERSIZE | ORIENTATION;
2192 nt_devmode->orientation = 1;
2193 nt_devmode->papersize = PAPER_LETTER;
2194 nt_devmode->paperlength = 0;
2195 nt_devmode->paperwidth = 0;
2196 nt_devmode->scale = 0x64;
2197 nt_devmode->copies = 1;
2198 nt_devmode->defaultsource = BIN_FORMSOURCE;
2199 nt_devmode->printquality = RES_HIGH; /* 0x0258 */
2200 nt_devmode->color = COLOR_MONOCHROME;
2201 nt_devmode->duplex = DUP_SIMPLEX;
2202 nt_devmode->yresolution = 0;
2203 nt_devmode->ttoption = TT_SUBDEV;
2204 nt_devmode->collate = COLLATE_FALSE;
2205 nt_devmode->icmmethod = 0;
2206 nt_devmode->icmintent = 0;
2207 nt_devmode->mediatype = 0;
2208 nt_devmode->dithertype = 0;
2210 /* non utilisés par un driver d'imprimante */
2211 nt_devmode->logpixels = 0;
2212 nt_devmode->bitsperpel = 0;
2213 nt_devmode->pelswidth = 0;
2214 nt_devmode->pelsheight = 0;
2215 nt_devmode->displayflags = 0;
2216 nt_devmode->displayfrequency = 0;
2217 nt_devmode->reserved1 = 0;
2218 nt_devmode->reserved2 = 0;
2219 nt_devmode->panningwidth = 0;
2220 nt_devmode->panningheight = 0;
2222 nt_devmode->private = NULL;
2226 /****************************************************************************
2227 Deepcopy an NT devicemode.
2228 ****************************************************************************/
2230 NT_DEVICEMODE *dup_nt_devicemode(NT_DEVICEMODE *nt_devicemode)
2232 NT_DEVICEMODE *new_nt_devicemode = NULL;
2234 if ((new_nt_devicemode = (NT_DEVICEMODE *)memdup(nt_devicemode, sizeof(NT_DEVICEMODE))) == NULL) {
2235 DEBUG(0,("dup_nt_devicemode: malloc fail.\n"));
2239 new_nt_devicemode->private = NULL;
2240 if (nt_devicemode->private != NULL) {
2241 if ((new_nt_devicemode->private = memdup(nt_devicemode->private, nt_devicemode->driverextra)) == NULL) {
2242 SAFE_FREE(new_nt_devicemode);
2243 DEBUG(0,("dup_nt_devicemode: malloc fail.\n"));
2248 return new_nt_devicemode;
2251 /****************************************************************************
2252 Clean up and deallocate a (maybe partially) allocated NT_DEVICEMODE.
2253 ****************************************************************************/
2255 void free_nt_devicemode(NT_DEVICEMODE **devmode_ptr)
2257 NT_DEVICEMODE *nt_devmode = *devmode_ptr;
2259 if(nt_devmode == NULL)
2262 DEBUG(106,("free_nt_devicemode: deleting DEVMODE\n"));
2264 SAFE_FREE(nt_devmode->private);
2265 SAFE_FREE(*devmode_ptr);
2268 /****************************************************************************
2269 Clean up and deallocate a (maybe partially) allocated NT_PRINTER_INFO_LEVEL_2.
2270 ****************************************************************************/
2271 static void free_nt_printer_info_level_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr)
2273 NT_PRINTER_INFO_LEVEL_2 *info = *info_ptr;
2274 NT_PRINTER_PARAM *param_ptr;
2279 DEBUG(106,("free_nt_printer_info_level_2: deleting info\n"));
2281 free_nt_devicemode(&info->devmode);
2283 for(param_ptr = info->specific; param_ptr; ) {
2284 NT_PRINTER_PARAM *tofree = param_ptr;
2286 param_ptr = param_ptr->next;
2287 free_nt_printer_param(&tofree);
2290 SAFE_FREE(*info_ptr);
2294 /****************************************************************************
2295 ****************************************************************************/
2296 static int unpack_devicemode(NT_DEVICEMODE **nt_devmode, char *buf, int buflen)
2300 NT_DEVICEMODE devmode;
2302 ZERO_STRUCT(devmode);
2304 len += tdb_unpack(buf+len, buflen-len, "p", nt_devmode);
2306 if (!*nt_devmode) return len;
2308 len += tdb_unpack(buf+len, buflen-len, "ffwwwwwwwwwwwwwwwwwwddddddddddddddp",
2312 &devmode.specversion,
2313 &devmode.driverversion,
2315 &devmode.driverextra,
2316 &devmode.orientation,
2318 &devmode.paperlength,
2319 &devmode.paperwidth,
2322 &devmode.defaultsource,
2323 &devmode.printquality,
2326 &devmode.yresolution,
2332 &devmode.bitsperpel,
2334 &devmode.pelsheight,
2335 &devmode.displayflags,
2336 &devmode.displayfrequency,
2340 &devmode.dithertype,
2343 &devmode.panningwidth,
2344 &devmode.panningheight,
2347 if (devmode.private) {
2348 /* the len in tdb_unpack is an int value and
2349 * devmode.driverextra is only a short
2351 len += tdb_unpack(buf+len, buflen-len, "B", &extra_len, &devmode.private);
2352 devmode.driverextra=(uint16)extra_len;
2354 /* check to catch an invalid TDB entry so we don't segfault */
2355 if (devmode.driverextra == 0) {
2356 devmode.private = NULL;
2360 *nt_devmode = (NT_DEVICEMODE *)memdup(&devmode, sizeof(devmode));
2362 DEBUG(8,("Unpacked devicemode [%s](%s)\n", devmode.devicename, devmode.formname));
2363 if (devmode.private)
2364 DEBUG(8,("with a private section of %d bytes\n", devmode.driverextra));
2369 /****************************************************************************
2370 ****************************************************************************/
2371 static int unpack_specifics(NT_PRINTER_PARAM **list, char *buf, int buflen)
2374 NT_PRINTER_PARAM param, *p;
2379 len += tdb_unpack(buf+len, buflen-len, "p", &p);
2382 len += tdb_unpack(buf+len, buflen-len, "fdB",
2388 *list = memdup(¶m, sizeof(param));
2390 DEBUG(8,("specific: [%s], len: %d\n", param.value, param.data_len));
2396 static void map_to_os2_driver(fstring drivername)
2398 static BOOL initialised=False;
2399 static fstring last_from,last_to;
2400 char *mapfile = lp_os2_driver_map();
2401 char **lines = NULL;
2405 if (!strlen(drivername))
2412 *last_from = *last_to = 0;
2416 if (strequal(drivername,last_from)) {
2417 DEBUG(3,("Mapped Windows driver %s to OS/2 driver %s\n",drivername,last_to));
2418 fstrcpy(drivername,last_to);
2422 lines = file_lines_load(mapfile, &numlines);
2423 if (numlines == 0) {
2424 DEBUG(0,("No entries in OS/2 driver map %s\n",mapfile));
2428 DEBUG(4,("Scanning OS/2 driver map %s\n",mapfile));
2430 for( i = 0; i < numlines; i++) {
2431 char *nt_name = lines[i];
2432 char *os2_name = strchr(nt_name,'=');
2439 while (isspace(*nt_name))
2442 if (!*nt_name || strchr("#;",*nt_name))
2446 int l = strlen(nt_name);
2447 while (l && isspace(nt_name[l-1])) {
2453 while (isspace(*os2_name))
2457 int l = strlen(os2_name);
2458 while (l && isspace(os2_name[l-1])) {
2464 if (strequal(nt_name,drivername)) {
2465 DEBUG(3,("Mapped windows driver %s to os2 driver%s\n",drivername,os2_name));
2466 fstrcpy(last_from,drivername);
2467 fstrcpy(last_to,os2_name);
2468 fstrcpy(drivername,os2_name);
2469 file_lines_free(lines);
2474 file_lines_free(lines);
2477 /****************************************************************************
2478 get a default printer info 2 struct
2479 ****************************************************************************/
2480 static WERROR get_a_printer_2_default(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstring sharename)
2483 NT_PRINTER_INFO_LEVEL_2 info;
2487 snum = lp_servicenumber(sharename);
2489 slprintf(info.servername, sizeof(info.servername)-1, "\\\\%s", get_called_name());
2490 slprintf(info.printername, sizeof(info.printername)-1, "\\\\%s\\%s",
2491 get_called_name(), sharename);
2492 fstrcpy(info.sharename, sharename);
2493 fstrcpy(info.portname, SAMBA_PRINTER_PORT_NAME);
2494 fstrcpy(info.drivername, lp_printerdriver(snum));
2496 /* by setting the driver name to an empty string, a local NT admin
2497 can now run the **local** APW to install a local printer driver
2498 for a Samba shared printer in 2.2. Without this, drivers **must** be
2499 installed on the Samba server for NT clients --jerry */
2500 #if 0 /* JERRY --do not uncomment-- */
2501 if (!*info.drivername)
2502 fstrcpy(info.drivername, "NO DRIVER AVAILABLE FOR THIS PRINTER");
2506 DEBUG(10,("get_a_printer_2_default: driver name set to [%s]\n", info.drivername));
2508 pstrcpy(info.comment, "");
2509 fstrcpy(info.printprocessor, "winprint");
2510 fstrcpy(info.datatype, "RAW");
2512 info.attributes = PRINTER_ATTRIBUTE_SHARED | PRINTER_ATTRIBUTE_NETWORK; /* attributes */
2514 info.starttime = 0; /* Minutes since 12:00am GMT */
2515 info.untiltime = 0; /* Minutes since 12:00am GMT */
2517 info.default_priority = 1;
2518 info.setuptime = (uint32)time(NULL);
2521 * I changed this as I think it is better to have a generic
2522 * DEVMODE than to crash Win2k explorer.exe --jerry
2523 * See the HP Deskjet 990c Win2k drivers for an example.
2525 * However the default devmode appears to cause problems
2526 * with the HP CLJ 8500 PCL driver. Hence the addition of
2527 * the "default devmode" parameter --jerry 22/01/2002
2530 if (lp_default_devmode(snum)) {
2531 if ((info.devmode = construct_nt_devicemode(info.printername)) == NULL)
2535 info.devmode = NULL;
2538 /* This will get the current RPC talloc context, but we should be
2539 passing this as a parameter... fixme... JRA ! */
2541 if (!nt_printing_getsec(get_talloc_ctx(), sharename, &info.secdesc_buf))
2544 *info_ptr = (NT_PRINTER_INFO_LEVEL_2 *)memdup(&info, sizeof(info));
2546 DEBUG(0,("get_a_printer_2_default: malloc fail.\n"));
2554 free_nt_devicemode(&info.devmode);
2555 return WERR_ACCESS_DENIED;
2558 /****************************************************************************
2559 ****************************************************************************/
2560 static WERROR get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstring sharename)
2563 NT_PRINTER_INFO_LEVEL_2 info;
2565 TDB_DATA kbuf, dbuf;
2566 fstring printername;
2570 slprintf(key, sizeof(key)-1, "%s%s", PRINTERS_PREFIX, sharename);
2573 kbuf.dsize = strlen(key)+1;
2575 dbuf = tdb_fetch(tdb_printers, kbuf);
2577 return get_a_printer_2_default(info_ptr, sharename);
2579 len += tdb_unpack(dbuf.dptr+len, dbuf.dsize-len, "dddddddddddfffffPfffff",
2582 &info.default_priority,
2599 info.printprocessor,
2603 /* Samba has to have shared raw drivers. */
2604 info.attributes |= (PRINTER_ATTRIBUTE_SHARED | PRINTER_ATTRIBUTE_NETWORK);
2606 /* Restore the stripped strings. */
2607 slprintf(info.servername, sizeof(info.servername)-1, "\\\\%s", get_called_name());
2608 slprintf(printername, sizeof(printername)-1, "\\\\%s\\%s", get_called_name(),
2610 fstrcpy(info.printername, printername);
2612 len += unpack_devicemode(&info.devmode,dbuf.dptr+len, dbuf.dsize-len);
2615 * Some client drivers freak out if there is a NULL devmode
2616 * (probably the driver is not checking before accessing
2617 * the devmode pointer) --jerry
2619 * See comments in get_a_printer_2_default()
2622 if (lp_default_devmode(lp_servicenumber(sharename)) && !info.devmode)
2624 DEBUG(8,("get_a_printer_2: Constructing a default device mode for [%s]\n",
2626 info.devmode = construct_nt_devicemode(printername);
2629 len += unpack_specifics(&info.specific,dbuf.dptr+len, dbuf.dsize-len);
2631 /* This will get the current RPC talloc context, but we should be
2632 passing this as a parameter... fixme... JRA ! */
2634 nt_printing_getsec(get_talloc_ctx(), sharename, &info.secdesc_buf);
2636 /* Fix for OS/2 drivers. */
2638 if (get_remote_arch() == RA_OS2)
2639 map_to_os2_driver(info.drivername);
2641 SAFE_FREE(dbuf.dptr);
2642 *info_ptr=memdup(&info, sizeof(info));
2644 DEBUG(9,("Unpacked printer [%s] name [%s] running driver [%s]\n",
2645 sharename, info.printername, info.drivername));
2650 /****************************************************************************
2651 debugging function, dump at level 6 the struct in the logs
2652 ****************************************************************************/
2653 static uint32 dump_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
2656 NT_PRINTER_INFO_LEVEL_2 *info2;
2658 DEBUG(106,("Dumping printer at level [%d]\n", level));
2664 if (printer.info_2 == NULL)
2668 info2=printer.info_2;
2670 DEBUGADD(106,("attributes:[%d]\n", info2->attributes));
2671 DEBUGADD(106,("priority:[%d]\n", info2->priority));
2672 DEBUGADD(106,("default_priority:[%d]\n", info2->default_priority));
2673 DEBUGADD(106,("starttime:[%d]\n", info2->starttime));
2674 DEBUGADD(106,("untiltime:[%d]\n", info2->untiltime));
2675 DEBUGADD(106,("status:[%d]\n", info2->status));
2676 DEBUGADD(106,("cjobs:[%d]\n", info2->cjobs));
2677 DEBUGADD(106,("averageppm:[%d]\n", info2->averageppm));
2678 DEBUGADD(106,("changeid:[%d]\n", info2->changeid));
2679 DEBUGADD(106,("c_setprinter:[%d]\n", info2->c_setprinter));
2680 DEBUGADD(106,("setuptime:[%d]\n", info2->setuptime));
2682 DEBUGADD(106,("servername:[%s]\n", info2->servername));
2683 DEBUGADD(106,("printername:[%s]\n", info2->printername));
2684 DEBUGADD(106,("sharename:[%s]\n", info2->sharename));
2685 DEBUGADD(106,("portname:[%s]\n", info2->portname));
2686 DEBUGADD(106,("drivername:[%s]\n", info2->drivername));
2687 DEBUGADD(106,("comment:[%s]\n", info2->comment));
2688 DEBUGADD(106,("location:[%s]\n", info2->location));
2689 DEBUGADD(106,("sepfile:[%s]\n", info2->sepfile));
2690 DEBUGADD(106,("printprocessor:[%s]\n", info2->printprocessor));
2691 DEBUGADD(106,("datatype:[%s]\n", info2->datatype));
2692 DEBUGADD(106,("parameters:[%s]\n", info2->parameters));
2698 DEBUGADD(106,("dump_a_printer: Level %u not implemented\n", (unsigned int)level ));
2706 /****************************************************************************
2707 Get the parameters we can substitute in an NT print job.
2708 ****************************************************************************/
2710 void get_printer_subst_params(int snum, fstring *printername, fstring *sharename, fstring *portname)
2712 NT_PRINTER_INFO_LEVEL *printer = NULL;
2714 **printername = **sharename = **portname = '\0';
2716 if (!W_ERROR_IS_OK(get_a_printer(&printer, 2, lp_servicename(snum))))
2719 fstrcpy(*printername, printer->info_2->printername);
2720 fstrcpy(*sharename, printer->info_2->sharename);
2721 fstrcpy(*portname, printer->info_2->portname);
2723 free_a_printer(&printer, 2);
2726 /****************************************************************************
2727 Update the changeid time.
2728 This is SO NASTY as some drivers need this to change, others need it
2729 static. This value will change every second, and I must hope that this
2730 is enough..... DON'T CHANGE THIS CODE WITHOUT A TEST MATRIX THE SIZE OF
2732 ****************************************************************************/
2734 static uint32 rev_changeid(void)
2738 get_process_uptime(&tv);
2741 /* Return changeid as msec since spooler restart */
2742 return tv.tv_sec * 1000 + tv.tv_usec / 1000;
2745 * This setting seems to work well but is too untested
2746 * to replace the above calculation. Left in for experiementation
2747 * of the reader --jerry (Tue Mar 12 09:15:05 CST 2002)
2749 return tv.tv_sec * 10 + tv.tv_usec / 100000;
2754 * The function below are the high level ones.
2755 * only those ones must be called from the spoolss code.
2759 /****************************************************************************
2760 Modify a printer. This is called from SETPRINTERDATA/DELETEPRINTERDATA.
2761 ****************************************************************************/
2763 WERROR mod_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
2767 dump_a_printer(printer, level);
2774 * Update the changestamp. Emperical tests show that the
2775 * ChangeID is always updated,but c_setprinter is
2776 * global spooler variable (not per printer).
2779 /* ChangeID **must** be increasing over the lifetime
2780 of client's spoolss service in order for the
2781 client's cache to show updates */
2783 printer.info_2->changeid = rev_changeid();
2786 * Because one day someone will ask:
2787 * NT->NT An admin connection to a remote
2788 * printer show changes imeediately in
2789 * the properities dialog
2791 * A non-admin connection will only show the
2792 * changes after viewing the properites page
2793 * 2 times. Seems to be related to a
2794 * race condition in the client between the spooler
2795 * updating the local cache and the Explorer.exe GUI
2796 * actually displaying the properties.
2798 * This is fixed in Win2k. admin/non-admin
2799 * connections both display changes immediately.
2804 result=update_a_printer_2(printer.info_2);
2808 result=WERR_UNKNOWN_LEVEL;
2815 /****************************************************************************
2816 Initialize printer devmode & data with previously saved driver init values.
2817 ****************************************************************************/
2819 static uint32 set_driver_init_2(NT_PRINTER_INFO_LEVEL_2 *info_ptr)
2823 TDB_DATA kbuf, dbuf;
2824 NT_PRINTER_PARAM *current;
2825 NT_PRINTER_INFO_LEVEL_2 info;
2828 * Delete any printer data 'specifics' already set. When called for driver
2829 * replace, there will generally be some, but during an add printer, there
2830 * should not be any (if there are delete them).
2832 while ( (current=info_ptr->specific) != NULL ) {
2833 info_ptr->specific=current->next;
2834 SAFE_FREE(current->data);
2840 slprintf(key, sizeof(key)-1, "%s%s", DRIVER_INIT_PREFIX, info_ptr->drivername);
2843 kbuf.dsize = strlen(key)+1;
2845 dbuf = tdb_fetch(tdb_drivers, kbuf);
2848 * When changing to a driver that has no init info in the tdb, remove
2849 * the previous drivers init info and leave the new on blank.
2851 free_nt_devicemode(&info_ptr->devmode);
2856 * Get the saved DEVMODE..
2858 len += unpack_devicemode(&info.devmode,dbuf.dptr+len, dbuf.dsize-len);
2861 * The saved DEVMODE contains the devicename from the printer used during
2862 * the initialization save. Change it to reflect the new printer.
2864 ZERO_STRUCT(info.devmode->devicename);
2865 fstrcpy(info.devmode->devicename, info_ptr->printername);
2869 * NT/2k does not change out the entire DeviceMode of a printer
2870 * when changing the driver. Only the driverextra, private, &
2871 * driverversion fields. --jerry (Thu Mar 14 08:58:43 CST 2002)
2877 * Bind the saved DEVMODE to the new the printer.
2879 free_nt_devicemode(&info_ptr->devmode);
2880 info_ptr->devmode = info.devmode;
2882 /* copy the entire devmode if we currently don't have one */
2884 if (!info_ptr->devmode) {
2885 DEBUG(10,("set_driver_init_2: Current Devmode is NULL. Copying entire Device Mode\n"));
2886 info_ptr->devmode = info.devmode;
2889 /* only set the necessary fields */
2891 DEBUG(10,("set_driver_init_2: Setting driverversion [0x%x] and private data [0x%x]\n",
2892 info.devmode->driverversion, info.devmode->driverextra));
2894 info_ptr->devmode->driverversion = info.devmode->driverversion;
2896 SAFE_FREE(info_ptr->devmode->private);
2897 info_ptr->devmode->private = NULL;
2899 if (info.devmode->driverversion)
2900 info_ptr->devmode->private = memdup(info.devmode->private, info.devmode->driverversion);
2902 free_nt_devicemode(&info.devmode);
2906 DEBUG(10,("set_driver_init_2: Set printer [%s] init DEVMODE for driver [%s]\n",
2907 info_ptr->printername, info_ptr->drivername));
2910 * Add the printer data 'specifics' to the new printer
2912 len += unpack_specifics(&info_ptr->specific,dbuf.dptr+len, dbuf.dsize-len);
2914 SAFE_FREE(dbuf.dptr);
2919 /****************************************************************************
2920 Initialize printer devmode & data with previously saved driver init values.
2921 When a printer is created using AddPrinter, the drivername bound to the
2922 printer is used to lookup previously saved driver initialization info, which
2923 is bound to the new printer.
2924 ****************************************************************************/
2926 uint32 set_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level)
2934 result=set_driver_init_2(printer->info_2);
2945 /****************************************************************************
2946 Pack up the DEVMODE and specifics for a printer into a 'driver init' entry
2947 in the tdb. Note: this is different from the driver entry and the printer
2948 entry. There should be a single driver init entry for each driver regardless
2949 of whether it was installed from NT or 2K. Technically, they should be
2950 different, but they work out to the same struct.
2951 ****************************************************************************/
2953 static uint32 update_driver_init_2(NT_PRINTER_INFO_LEVEL_2 *info)
2957 int buflen, len, ret;
2958 TDB_DATA kbuf, dbuf;
2965 len += pack_devicemode(info->devmode, buf+len, buflen-len);
2967 len += pack_specifics(info->specific, buf+len, buflen-len);
2969 if (buflen != len) {
2972 tb = (char *)Realloc(buf, len);
2974 DEBUG(0, ("update_driver_init_2: failed to enlarge buffer!\n"));
2983 slprintf(key, sizeof(key)-1, "%s%s", DRIVER_INIT_PREFIX, info->drivername);
2986 kbuf.dsize = strlen(key)+1;
2990 ret = tdb_store(tdb_drivers, kbuf, dbuf, TDB_REPLACE);
2994 DEBUG(8, ("update_driver_init_2: error updating printer init to tdb on disk\n"));
2998 DEBUG(10,("update_driver_init_2: Saved printer [%s] init DEVMODE & specifics for driver [%s]\n",
2999 info->sharename, info->drivername));
3004 /****************************************************************************
3005 Update (i.e. save) the driver init info (DEVMODE and specifics) for a printer
3006 ****************************************************************************/
3008 uint32 update_driver_init(NT_PRINTER_INFO_LEVEL printer, uint32 level)
3012 dump_a_printer(printer, level);
3018 result=update_driver_init_2(printer.info_2);
3029 /****************************************************************************
3030 Convert the printer data value, a REG_BINARY array, into an initialization
3031 DEVMODE. Note: the array must be parsed as if it was a DEVMODE in an rpc...
3032 got to keep the endians happy :).
3033 ****************************************************************************/
3035 static BOOL convert_driver_init(NT_PRINTER_PARAM *param, TALLOC_CTX *ctx, NT_DEVICEMODE *nt_devmode)
3037 BOOL result = False;
3041 ZERO_STRUCT(devmode);
3043 prs_init(&ps, 0, ctx, UNMARSHALL);
3044 ps.data_p = (char *)param->data;
3045 ps.buffer_size = param->data_len;
3047 if (spoolss_io_devmode("phantom DEVMODE", &ps, 0, &devmode))
3048 result = convert_devicemode("", &devmode, &nt_devmode);
3050 DEBUG(10,("convert_driver_init: error parsing DEVMODE\n"));
3055 /****************************************************************************
3056 Set the DRIVER_INIT info in the tdb. Requires Win32 client code that:
3058 1. Use the driver's config DLL to this UNC printername and:
3059 a. Call DrvPrintEvent with PRINTER_EVENT_INITIALIZE
3060 b. Call DrvConvertDevMode with CDM_DRIVER_DEFAULT to get default DEVMODE
3061 2. Call SetPrinterData with the 'magic' key and the DEVMODE as data.
3063 The last step triggers saving the "driver initialization" information for
3064 this printer into the tdb. Later, new printers that use this driver will
3065 have this initialization information bound to them. This simulates the
3066 driver initialization, as if it had run on the Samba server (as it would
3069 The Win32 client side code requirement sucks! But until we can run arbitrary
3070 Win32 printer driver code on any Unix that Samba runs on, we are stuck with it.
3072 It would have been easier to use SetPrinter because all the UNMARSHALLING of
3073 the DEVMODE is done there, but 2K/XP clients do not set the DEVMODE... think
3074 about it and you will realize why. JRR 010720
3075 ****************************************************************************/
3077 static WERROR save_driver_init_2(NT_PRINTER_INFO_LEVEL *printer, NT_PRINTER_PARAM *param)
3079 WERROR status = WERR_OK;
3080 TALLOC_CTX *ctx = NULL;
3081 NT_DEVICEMODE *nt_devmode = NULL;
3082 NT_DEVICEMODE *tmp_devmode = printer->info_2->devmode;
3085 * When the DEVMODE is already set on the printer, don't try to unpack it.
3088 if (!printer->info_2->devmode && param->data_len) {
3090 * Set devmode on printer info, so entire printer initialization can be
3094 if ((ctx = talloc_init()) == NULL)
3097 if ((nt_devmode = (NT_DEVICEMODE*)malloc(sizeof(NT_DEVICEMODE))) == NULL) {
3098 status = WERR_NOMEM;
3102 ZERO_STRUCTP(nt_devmode);
3105 * The DEVMODE is held in the 'data' component of the param in raw binary.
3106 * Convert it to to a devmode structure
3108 if (!convert_driver_init(param, ctx, nt_devmode)) {
3109 DEBUG(10,("save_driver_init_2: error converting DEVMODE\n"));
3110 status = WERR_INVALID_PARAM;
3114 printer->info_2->devmode = nt_devmode;
3118 * Pack up and add (or update) the DEVMODE and any current printer data to
3119 * a 'driver init' element in the tdb
3123 if (update_driver_init(*printer, 2)!=0) {
3124 DEBUG(10,("save_driver_init_2: error updating DEVMODE\n"));
3125 status = WERR_NOMEM;
3130 * If driver initialization info was successfully saved, set the current
3131 * printer to match it. This allows initialization of the current printer
3132 * as well as the driver.
3134 status = mod_a_printer(*printer, 2);
3135 if (!W_ERROR_IS_OK(status)) {
3136 DEBUG(10,("save_driver_init_2: error setting DEVMODE on printer [%s]\n",
3137 printer->info_2->printername));
3141 srv_spoolss_sendnotify(p, handle);
3145 talloc_destroy(ctx);
3147 SAFE_FREE(nt_devmode->private);
3148 SAFE_FREE(nt_devmode);
3149 printer->info_2->devmode = tmp_devmode;
3154 /****************************************************************************
3155 Update the driver init info (DEVMODE and specifics) for a printer
3156 ****************************************************************************/
3158 WERROR save_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level, NT_PRINTER_PARAM *param)
3160 WERROR status = WERR_OK;
3166 status=save_driver_init_2(printer, param);
3170 status=WERR_UNKNOWN_LEVEL;
3177 /****************************************************************************
3178 Get a NT_PRINTER_INFO_LEVEL struct. It returns malloced memory.
3179 ****************************************************************************/
3181 WERROR get_a_printer(NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level, fstring sharename)
3184 NT_PRINTER_INFO_LEVEL *printer = NULL;
3188 DEBUG(10,("get_a_printer: [%s] level %u\n", sharename, (unsigned int)level));
3194 if ((printer = (NT_PRINTER_INFO_LEVEL *)malloc(sizeof(NT_PRINTER_INFO_LEVEL))) == NULL) {
3195 DEBUG(0,("get_a_printer: malloc fail.\n"));
3198 ZERO_STRUCTP(printer);
3199 result=get_a_printer_2(&printer->info_2, sharename);
3200 if (W_ERROR_IS_OK(result)) {
3201 dump_a_printer(*printer, level);
3202 *pp_printer = printer;
3209 result=WERR_UNKNOWN_LEVEL;
3213 DEBUG(10,("get_a_printer: [%s] level %u returning %s\n", sharename, (unsigned int)level, werror_str(result)));
3218 /****************************************************************************
3219 Deletes a NT_PRINTER_INFO_LEVEL struct.
3220 ****************************************************************************/
3222 uint32 free_a_printer(NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level)
3225 NT_PRINTER_INFO_LEVEL *printer = *pp_printer;
3227 DEBUG(104,("freeing a printer at level [%d]\n", level));
3229 if (printer == NULL)
3236 if (printer->info_2 != NULL)
3238 free_nt_printer_info_level_2(&printer->info_2);
3252 SAFE_FREE(*pp_printer);
3256 /****************************************************************************
3257 ****************************************************************************/
3258 uint32 add_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
3261 DEBUG(104,("adding a printer at level [%d]\n", level));
3262 dump_a_printer_driver(driver, level);
3268 result=add_a_printer_driver_3(driver.info_3);
3274 result=add_a_printer_driver_6(driver.info_6);
3284 /****************************************************************************
3285 ****************************************************************************/
3286 WERROR get_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL *driver, uint32 level,
3287 fstring printername, fstring architecture, uint32 version)
3295 result=get_a_printer_driver_3(&driver->info_3, printername, architecture, version);
3303 if (W_ERROR_IS_OK(result))
3304 dump_a_printer_driver(*driver, level);
3308 /****************************************************************************
3309 ****************************************************************************/
3310 uint32 free_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
3318 NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3;
3319 if (driver.info_3 != NULL)
3321 info3=driver.info_3;
3322 SAFE_FREE(info3->dependentfiles);
3323 ZERO_STRUCTP(info3);
3335 NT_PRINTER_DRIVER_INFO_LEVEL_6 *info6;
3336 if (driver.info_6 != NULL)
3338 info6=driver.info_6;
3339 SAFE_FREE(info6->dependentfiles);
3340 SAFE_FREE(info6->previousnames);
3341 ZERO_STRUCTP(info6);
3359 /****************************************************************************
3360 Determine whether or not a particular driver is currently assigned
3362 ****************************************************************************/
3363 BOOL printer_driver_in_use (char *arch, char *driver)
3365 TDB_DATA kbuf, newkey, dbuf;
3366 NT_PRINTER_INFO_LEVEL_2 info;
3370 if (!nt_printing_init())
3373 DEBUG(5,("printer_driver_in_use: Beginning search through printers.tdb...\n"));
3375 /* loop through the printers.tdb and check for the drivername */
3376 for (kbuf = tdb_firstkey(tdb_printers); kbuf.dptr;
3377 newkey = tdb_nextkey(tdb_printers, kbuf), safe_free(kbuf.dptr), kbuf=newkey)
3380 dbuf = tdb_fetch(tdb_printers, kbuf);
3384 if (strncmp(kbuf.dptr, PRINTERS_PREFIX, strlen(PRINTERS_PREFIX)) != 0)
3387 ret = tdb_unpack(dbuf.dptr, dbuf.dsize, "dddddddddddfffffPfffff",
3390 &info.default_priority,
3407 info.printprocessor,
3411 SAFE_FREE(dbuf.dptr);
3414 DEBUG (0,("printer_driver_in_use: tdb_unpack failed for printer %s\n",
3419 DEBUG (10,("printer_driver_in_use: Printer - %s (%s)\n",
3420 info.printername, info.drivername));
3422 if (strcmp(info.drivername, driver) == 0)
3424 DEBUG(5,("printer_driver_in_use: Printer %s using %s\n",
3425 info.printername, driver));
3429 DEBUG(5,("printer_driver_in_use: Completed search through printers.tdb...\n"));
3433 /* report that the driver is in use by default */
3437 /****************************************************************************
3438 Remove a printer driver from the TDB. This assumes that the the driver was
3439 previously looked up.
3440 ***************************************************************************/
3441 WERROR delete_printer_driver (NT_PRINTER_DRIVER_INFO_LEVEL_3 *i)
3448 get_short_archi(arch, i->environment);
3449 slprintf(key, sizeof(key)-1, "%s%s/%d/%s", DRIVERS_PREFIX,
3450 arch, i->cversion, i->name);
3451 DEBUG(5,("delete_printer_driver: key = [%s]\n", key));
3454 kbuf.dsize=strlen(key)+1;
3456 if (tdb_delete(tdb_drivers, kbuf) == -1) {
3457 DEBUG (0,("delete_printer_driver: fail to delete %s!\n", key));
3458 return WERR_ACCESS_DENIED;
3461 DEBUG(5,("delete_printer_driver: [%s] driver delete successful.\n",
3466 /****************************************************************************
3467 ****************************************************************************/
3468 BOOL get_specific_param_by_index(NT_PRINTER_INFO_LEVEL printer, uint32 level, uint32 param_index,
3469 fstring value, uint8 **data, uint32 *type, uint32 *len)
3471 /* right now that's enough ! */
3472 NT_PRINTER_PARAM *param;
3475 param=printer.info_2->specific;
3477 while (param != NULL && i < param_index) {
3485 /* exited because it exist */
3487 StrnCpy(value, param->value, sizeof(fstring)-1);
3488 *data=(uint8 *)malloc(param->data_len*sizeof(uint8));
3491 ZERO_STRUCTP(*data);
3492 memcpy(*data, param->data, param->data_len);
3493 *len=param->data_len;
3497 /****************************************************************************
3498 ****************************************************************************/
3499 BOOL get_specific_param(NT_PRINTER_INFO_LEVEL printer, uint32 level,
3500 fstring value, uint8 **data, uint32 *type, uint32 *len)
3502 /* right now that's enough ! */
3503 NT_PRINTER_PARAM *param;
3505 DEBUG(10, ("get_specific_param\n"));
3507 param=printer.info_2->specific;
3509 while (param != NULL)
3511 #if 1 /* JRA - I think this should be case insensitive.... */
3512 if ( strequal(value, param->value)
3514 if ( !strcmp(value, param->value)
3516 && strlen(value)==strlen(param->value))
3524 DEBUGADD(10, ("get_specific_param: found one param\n"));
3525 /* exited because it exist */
3528 *data=(uint8 *)malloc(param->data_len*sizeof(uint8));
3531 memcpy(*data, param->data, param->data_len);
3532 *len=param->data_len;
3534 DEBUGADD(10, ("get_specific_param: exit true\n"));
3537 DEBUGADD(10, ("get_specific_param: exit false\n"));
3541 /****************************************************************************
3542 Store a security desc for a printer.
3543 ****************************************************************************/
3545 WERROR nt_printing_setsec(char *printername, SEC_DESC_BUF *secdesc_ctr)
3547 SEC_DESC_BUF *new_secdesc_ctr = NULL;
3548 SEC_DESC_BUF *old_secdesc_ctr = NULL;
3550 TALLOC_CTX *mem_ctx = NULL;
3554 mem_ctx = talloc_init();
3555 if (mem_ctx == NULL)
3558 /* The old owner and group sids of the security descriptor are not
3559 present when new ACEs are added or removed by changing printer
3560 permissions through NT. If they are NULL in the new security
3561 descriptor then copy them over from the old one. */
3563 if (!secdesc_ctr->sec->owner_sid || !secdesc_ctr->sec->grp_sid) {
3564 DOM_SID *owner_sid, *group_sid;
3565 SEC_ACL *dacl, *sacl;
3566 SEC_DESC *psd = NULL;
3569 nt_printing_getsec(mem_ctx, printername, &old_secdesc_ctr);
3571 /* Pick out correct owner and group sids */
3573 owner_sid = secdesc_ctr->sec->owner_sid ?
3574 secdesc_ctr->sec->owner_sid :
3575 old_secdesc_ctr->sec->owner_sid;
3577 group_sid = secdesc_ctr->sec->grp_sid ?
3578 secdesc_ctr->sec->grp_sid :
3579 old_secdesc_ctr->sec->grp_sid;
3581 dacl = secdesc_ctr->sec->dacl ?
3582 secdesc_ctr->sec->dacl :
3583 old_secdesc_ctr->sec->dacl;
3585 sacl = secdesc_ctr->sec->sacl ?
3586 secdesc_ctr->sec->sacl :
3587 old_secdesc_ctr->sec->sacl;
3589 /* Make a deep copy of the security descriptor */
3591 psd = make_sec_desc(mem_ctx, secdesc_ctr->sec->revision,
3592 owner_sid, group_sid,
3597 new_secdesc_ctr = make_sec_desc_buf(mem_ctx, size, psd);
3600 if (!new_secdesc_ctr) {
3601 new_secdesc_ctr = secdesc_ctr;
3604 /* Store the security descriptor in a tdb */
3606 prs_init(&ps, (uint32)sec_desc_size(new_secdesc_ctr->sec) +
3607 sizeof(SEC_DESC_BUF), mem_ctx, MARSHALL);
3609 if (!sec_io_desc_buf("nt_printing_setsec", &new_secdesc_ctr,
3611 status = WERR_BADFUNC;
3615 slprintf(key, sizeof(key)-1, "SECDESC/%s", printername);
3617 if (tdb_prs_store(tdb_printers, key, &ps)==0) {
3620 DEBUG(1,("Failed to store secdesc for %s\n", printername));
3621 status = WERR_BADFUNC;
3624 /* Free malloc'ed memory */
3630 talloc_destroy(mem_ctx);
3634 /****************************************************************************
3635 Construct a default security descriptor buffer for a printer.
3636 ****************************************************************************/
3638 static SEC_DESC_BUF *construct_default_printer_sdb(TALLOC_CTX *ctx)
3640 extern DOM_SID global_sam_sid;
3643 SEC_ACL *psa = NULL;
3644 SEC_DESC_BUF *sdb = NULL;
3645 SEC_DESC *psd = NULL;
3649 /* Create an ACE where Everyone is allowed to print */
3651 init_sec_access(&sa, PRINTER_ACE_PRINT);
3652 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
3653 sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
3655 /* Make the security descriptor owned by the Administrators group
3656 on the PDC of the domain. */
3658 if (secrets_fetch_domain_sid(lp_workgroup(), &owner_sid)) {
3659 sid_append_rid(&owner_sid, DOMAIN_USER_RID_ADMIN);
3662 /* Backup plan - make printer owned by admins.
3663 This should emulate a lanman printer as security
3664 settings can't be changed. */
3666 sid_copy(&owner_sid, &global_sam_sid);
3667 sid_append_rid(&owner_sid, DOMAIN_USER_RID_ADMIN);
3670 init_sec_access(&sa, PRINTER_ACE_FULL_CONTROL);
3671 init_sec_ace(&ace[1], &owner_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
3672 sa, SEC_ACE_FLAG_OBJECT_INHERIT |
3673 SEC_ACE_FLAG_INHERIT_ONLY);
3675 init_sec_access(&sa, PRINTER_ACE_FULL_CONTROL);
3676 init_sec_ace(&ace[2], &owner_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
3677 sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
3679 /* The ACL revision number in rpc_secdesc.h differs from the one
3680 created by NT when setting ACE entries in printer
3681 descriptors. NT4 complains about the property being edited by a
3684 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) != NULL) {
3685 psd = make_sec_desc(ctx, SEC_DESC_REVISION,
3687 NULL, psa, &sd_size);
3691 DEBUG(0,("construct_default_printer_sd: Failed to make SEC_DESC.\n"));
3695 sdb = make_sec_desc_buf(ctx, sd_size, psd);
3697 DEBUG(4,("construct_default_printer_sdb: size = %u.\n",
3698 (unsigned int)sd_size));
3703 /****************************************************************************
3704 Get a security desc for a printer.
3705 ****************************************************************************/
3707 BOOL nt_printing_getsec(TALLOC_CTX *ctx, char *printername, SEC_DESC_BUF **secdesc_ctr)
3713 if ((temp = strchr(printername + 2, '\\'))) {
3714 printername = temp + 1;
3717 /* Fetch security descriptor from tdb */
3719 slprintf(key, sizeof(key)-1, "SECDESC/%s", printername);
3721 if (tdb_prs_fetch(tdb_printers, key, &ps, ctx)!=0 ||
3722 !sec_io_desc_buf("nt_printing_getsec", secdesc_ctr, &ps, 1)) {
3724 DEBUG(4,("using default secdesc for %s\n", printername));
3726 if (!(*secdesc_ctr = construct_default_printer_sdb(ctx))) {
3730 /* Save default security descriptor for later */
3732 prs_init(&ps, (uint32)sec_desc_size((*secdesc_ctr)->sec) +
3733 sizeof(SEC_DESC_BUF), ctx, MARSHALL);
3735 if (sec_io_desc_buf("nt_printing_setsec", secdesc_ctr, &ps, 1))
3736 tdb_prs_store(tdb_printers, key, &ps);
3743 /* If security descriptor is owned by S-1-1-0 and winbindd is up,
3744 this security descriptor has been created when winbindd was
3745 down. Take ownership of security descriptor. */
3747 if (sid_equal((*secdesc_ctr)->sec->owner_sid, &global_sid_World)) {
3750 /* Change sd owner to workgroup administrator */
3752 if (secrets_fetch_domain_sid(lp_workgroup(), &owner_sid)) {
3753 SEC_DESC_BUF *new_secdesc_ctr = NULL;
3754 SEC_DESC *psd = NULL;
3759 sid_append_rid(&owner_sid, DOMAIN_USER_RID_ADMIN);
3761 psd = make_sec_desc(ctx, (*secdesc_ctr)->sec->revision,
3763 (*secdesc_ctr)->sec->grp_sid,
3764 (*secdesc_ctr)->sec->sacl,
3765 (*secdesc_ctr)->sec->dacl,
3768 new_secdesc_ctr = make_sec_desc_buf(ctx, size, psd);
3770 /* Swap with other one */
3772 *secdesc_ctr = new_secdesc_ctr;
3776 nt_printing_setsec(printername, *secdesc_ctr);
3780 if (DEBUGLEVEL >= 10) {
3781 SEC_ACL *the_acl = (*secdesc_ctr)->sec->dacl;
3784 DEBUG(10, ("secdesc_ctr for %s has %d aces:\n",
3785 printername, the_acl->num_aces));
3787 for (i = 0; i < the_acl->num_aces; i++) {
3790 sid_to_string(sid_str, &the_acl->ace[i].trustee);
3792 DEBUG(10, ("%s %d %d 0x%08x\n", sid_str,
3793 the_acl->ace[i].type, the_acl->ace[i].flags,
3794 the_acl->ace[i].info.mask));
3804 1: level not implemented
3805 2: file doesn't exist
3806 3: can't allocate memory
3807 4: can't free memory
3808 5: non existant struct
3812 A printer and a printer driver are 2 different things.
3813 NT manages them separatelly, Samba does the same.
3814 Why ? Simply because it's easier and it makes sense !
3816 Now explanation: You have 3 printers behind your samba server,
3817 2 of them are the same make and model (laser A and B). But laser B
3818 has an 3000 sheet feeder and laser A doesn't such an option.
3819 Your third printer is an old dot-matrix model for the accounting :-).
3821 If the /usr/local/samba/lib directory (default dir), you will have
3822 5 files to describe all of this.
3824 3 files for the printers (1 by printer):
3827 NTprinter_accounting
3828 2 files for the drivers (1 for the laser and 1 for the dot matrix)
3829 NTdriver_printer model X
3830 NTdriver_printer model Y
3832 jfm: I should use this comment for the text file to explain
3833 same thing for the forms BTW.
3834 Je devrais mettre mes commentaires en francais, ca serait mieux :-)
3838 /* Convert generic access rights to printer object specific access rights.
3839 It turns out that NT4 security descriptors use generic access rights and
3840 NT5 the object specific ones. */
3842 void map_printer_permissions(SEC_DESC *sd)
3846 for (i = 0; sd->dacl && i < sd->dacl->num_aces; i++) {
3847 se_map_generic(&sd->dacl->ace[i].info.mask,
3848 &printer_generic_mapping);
3852 /****************************************************************************
3853 Check a user has permissions to perform the given operation. We use the
3854 permission constants defined in include/rpc_spoolss.h to check the various
3855 actions we perform when checking printer access.
3857 PRINTER_ACCESS_ADMINISTER:
3858 print_queue_pause, print_queue_resume, update_printer_sec,
3859 update_printer, spoolss_addprinterex_level_2,
3860 _spoolss_setprinterdata
3865 JOB_ACCESS_ADMINISTER:
3866 print_job_delete, print_job_pause, print_job_resume,
3869 ****************************************************************************/
3870 BOOL print_access_check(struct current_user *user, int snum, int access_type)
3872 SEC_DESC_BUF *secdesc = NULL;
3873 uint32 access_granted;
3877 TALLOC_CTX *mem_ctx = NULL;
3878 extern struct current_user current_user;
3880 /* If user is NULL then use the current_user structure */
3883 user = ¤t_user;
3885 /* Always allow root or printer admins to do anything */
3887 if (user->uid == 0 ||
3888 user_in_list(uidtoname(user->uid), lp_printer_admin(snum))) {
3892 /* Get printer name */
3894 pname = PRINTERNAME(snum);
3896 if (!pname || !*pname) {
3901 /* Get printer security descriptor */
3903 if(!(mem_ctx = talloc_init())) {
3908 nt_printing_getsec(mem_ctx, pname, &secdesc);
3910 if (access_type == JOB_ACCESS_ADMINISTER) {
3911 SEC_DESC_BUF *parent_secdesc = secdesc;
3913 /* Create a child security descriptor to check permissions
3914 against. This is because print jobs are child objects
3915 objects of a printer. */
3917 secdesc = se_create_child_secdesc(mem_ctx, parent_secdesc->sec, False);
3919 /* Now this is the bit that really confuses me. The access
3920 type needs to be changed from JOB_ACCESS_ADMINISTER to
3921 PRINTER_ACCESS_ADMINISTER for this to work. Something
3922 to do with the child (job) object becoming like a
3925 access_type = PRINTER_ACCESS_ADMINISTER;
3930 map_printer_permissions(secdesc->sec);
3932 result = se_access_check(secdesc->sec, user->nt_user_token, access_type,
3933 &access_granted, &status);
3935 DEBUG(4, ("access check was %s\n", result ? "SUCCESS" : "FAILURE"));
3937 talloc_destroy(mem_ctx);
3945 /****************************************************************************
3946 Check the time parameters allow a print operation.
3947 *****************************************************************************/
3949 BOOL print_time_access_check(int snum)
3951 NT_PRINTER_INFO_LEVEL *printer = NULL;
3953 time_t now = time(NULL);
3957 if (!W_ERROR_IS_OK(get_a_printer(&printer, 2, lp_servicename(snum))))
3960 if (printer->info_2->starttime == 0 && printer->info_2->untiltime == 0)
3964 mins = (uint32)t->tm_hour*60 + (uint32)t->tm_min;
3966 if (mins >= printer->info_2->starttime && mins <= printer->info_2->untiltime)
3969 free_a_printer(&printer, 2);
3977 #if 0 /* JERRY - not used */
3978 /****************************************************************************
3979 Attempt to write a default device.
3980 *****************************************************************************/
3982 WERROR printer_write_default_dev(int snum, const PRINTER_DEFAULT *printer_default)
3984 NT_PRINTER_INFO_LEVEL *printer = NULL;
3988 * Don't bother if no default devicemode was sent.
3991 if (printer_default->devmode_cont.devmode == NULL)
3994 result = get_a_printer(&printer, 2, lp_servicename(snum));
3995 if (!W_ERROR_IS_OK(result)) return result;
3998 * Just ignore it if we already have a devmode.
4001 if (printer->info_2->devmode != NULL)
4005 * We don't have a devicemode and we're trying to write
4006 * one. Check we have the access needed.
4008 DEBUG(5,("printer_write_default_dev: access: %x\n", printer_default->access_required));
4010 if ( (printer_default->access_required & PRINTER_ACCESS_ADMINISTER) !=
4011 PRINTER_ACCESS_ADMINISTER) {
4012 DEBUG(5,("printer_write_default_dev: invalid request access to update: %x\n", printer_default->access_required));
4013 result = WERR_ACCESS_DENIED;
4017 if (!print_access_check(NULL, snum, PRINTER_ACCESS_ADMINISTER)) {
4018 DEBUG(5,("printer_write_default_dev: Access denied for printer %s\n",
4019 lp_servicename(snum) ));
4020 result = WERR_ACCESS_DENIED;
4021 /*result = NT_STATUS_NO_PROBLEMO;*/
4025 DEBUG(5,("printer_write_default_dev: updating, check OK.\n"));
4028 * Convert the on the wire devicemode format to the internal one.
4031 if (!convert_devicemode(printer->info_2->printername,
4032 printer_default->devmode_cont.devmode,
4033 &printer->info_2->devmode)) {
4034 result = WERR_NOMEM;
4039 * Finally write back to the tdb.
4042 result = mod_a_printer(*printer, 2);
4046 free_a_printer(&printer, 2);