2 * Unix SMB/Netbios implementation.
4 * RPC Pipe client / server routines
5 * Copyright (C) Andrew Tridgell 1992-2000,
6 * Copyright (C) Jean François Micouleau 1998-2000.
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 extern DOM_SID global_sid_World;
27 static TDB_CONTEXT *tdb_forms; /* used for forms files */
28 static TDB_CONTEXT *tdb_drivers; /* used for driver files */
29 static TDB_CONTEXT *tdb_printers; /* used for printers files */
31 #define FORMS_PREFIX "FORMS/"
32 #define DRIVERS_PREFIX "DRIVERS/"
33 #define DRIVER_INIT_PREFIX "DRIVER_INIT/"
34 #define PRINTERS_PREFIX "PRINTERS/"
35 #define SECDESC_PREFIX "SECDESC/"
37 #define NTDRIVERS_DATABASE_VERSION_1 1
38 #define NTDRIVERS_DATABASE_VERSION_2 2
40 #define NTDRIVERS_DATABASE_VERSION NTDRIVERS_DATABASE_VERSION_2
42 /* Map generic permissions to printer object specific permissions */
44 struct generic_mapping printer_generic_mapping = {
51 /* We need one default form to support our default printer. Msoft adds the
52 forms it wants and in the ORDER it wants them (note: DEVMODE papersize is an
53 array index). Letter is always first, so (for the current code) additions
54 always put things in the correct order. */
55 static nt_forms_struct default_forms[] = {
56 {"Letter",0x1,0x34b5c,0x44368,0x0,0x0,0x34b5c,0x44368},
57 {"Letter Small",0x1,0x34b5c,0x44368,0x0,0x0,0x34b5c,0x44368},
58 {"Tabloid",0x1,0x44368,0x696b8,0x0,0x0,0x44368,0x696b8},
59 {"Ledger",0x1,0x696b8,0x44368,0x0,0x0,0x696b8,0x44368},
60 {"Legal",0x1,0x34b5c,0x56d10,0x0,0x0,0x34b5c,0x56d10},
61 {"Statement",0x1,0x221b4,0x34b5c,0x0,0x0,0x221b4,0x34b5c},
62 {"Executive",0x1,0x2cf56,0x411cc,0x0,0x0,0x2cf56,0x411cc},
63 {"A3",0x1,0x48828,0x668a0,0x0,0x0,0x48828,0x668a0},
64 {"A4",0x1,0x33450,0x48828,0x0,0x0,0x33450,0x48828},
65 {"A4 Small",0x1,0x33450,0x48828,0x0,0x0,0x33450,0x48828},
66 {"A5",0x1,0x24220,0x33450,0x0,0x0,0x24220,0x33450},
67 {"B4 (JIS)",0x1,0x3ebe8,0x58de0,0x0,0x0,0x3ebe8,0x58de0},
68 {"B5 (JIS)",0x1,0x2c6f0,0x3ebe8,0x0,0x0,0x2c6f0,0x3ebe8},
69 {"Folio",0x1,0x34b5c,0x509d8,0x0,0x0,0x34b5c,0x509d8},
70 {"Quarto",0x1,0x347d8,0x43238,0x0,0x0,0x347d8,0x43238},
71 {"10x14",0x1,0x3e030,0x56d10,0x0,0x0,0x3e030,0x56d10},
72 {"11x17",0x1,0x44368,0x696b8,0x0,0x0,0x44368,0x696b8},
73 {"Note",0x1,0x34b5c,0x44368,0x0,0x0,0x34b5c,0x44368},
74 {"Envelope #9",0x1,0x18079,0x37091,0x0,0x0,0x18079,0x37091},
75 {"Envelope #10",0x1,0x19947,0x3ae94,0x0,0x0,0x19947,0x3ae94},
76 {"Envelope #11",0x1,0x1be7c,0x40565,0x0,0x0,0x1be7c,0x40565},
77 {"Envelope #12",0x1,0x1d74a,0x44368,0x0,0x0,0x1d74a,0x44368},
78 {"Envelope #14",0x1,0x1f018,0x47504,0x0,0x0,0x1f018,0x47504},
79 {"C size sheet",0x1,0x696b8,0x886d0,0x0,0x0,0x696b8,0x886d0},
80 {"D size sheet",0x1,0x886d0,0xd2d70,0x0,0x0,0x886d0,0xd2d70},
81 {"E size sheet",0x1,0xd2d70,0x110da0,0x0,0x0,0xd2d70,0x110da0},
82 {"Envelope DL",0x1,0x1adb0,0x35b60,0x0,0x0,0x1adb0,0x35b60},
83 {"Envelope C5",0x1,0x278d0,0x37e88,0x0,0x0,0x278d0,0x37e88},
84 {"Envelope C3",0x1,0x4f1a0,0x6fd10,0x0,0x0,0x4f1a0,0x6fd10},
85 {"Envelope C4",0x1,0x37e88,0x4f1a0,0x0,0x0,0x37e88,0x4f1a0},
86 {"Envelope C6",0x1,0x1bd50,0x278d0,0x0,0x0,0x1bd50,0x278d0},
87 {"Envelope C65",0x1,0x1bd50,0x37e88,0x0,0x0,0x1bd50,0x37e88},
88 {"Envelope B4",0x1,0x3d090,0x562e8,0x0,0x0,0x3d090,0x562e8},
89 {"Envelope B5",0x1,0x2af80,0x3d090,0x0,0x0,0x2af80,0x3d090},
90 {"Envelope B6",0x1,0x2af80,0x1e848,0x0,0x0,0x2af80,0x1e848},
91 {"Envelope",0x1,0x1adb0,0x38270,0x0,0x0,0x1adb0,0x38270},
92 {"Envelope Monarch",0x1,0x18079,0x2e824,0x0,0x0,0x18079,0x2e824},
93 {"6 3/4 Envelope",0x1,0x167ab,0x284ec,0x0,0x0,0x167ab,0x284ec},
94 {"US Std Fanfold",0x1,0x5c3e1,0x44368,0x0,0x0,0x5c3e1,0x44368},
95 {"German Std Fanfold",0x1,0x34b5c,0x4a6a0,0x0,0x0,0x34b5c,0x4a6a0},
96 {"German Legal Fanfold",0x1,0x34b5c,0x509d8,0x0,0x0,0x34b5c,0x509d8},
97 {"B4 (ISO)",0x1,0x3d090,0x562e8,0x0,0x0,0x3d090,0x562e8},
98 {"Japanese Postcard",0x1,0x186a0,0x24220,0x0,0x0,0x186a0,0x24220},
99 {"9x11",0x1,0x37cf8,0x44368,0x0,0x0,0x37cf8,0x44368},
100 {"10x11",0x1,0x3e030,0x44368,0x0,0x0,0x3e030,0x44368},
101 {"15x11",0x1,0x5d048,0x44368,0x0,0x0,0x5d048,0x44368},
102 {"Envelope Invite",0x1,0x35b60,0x35b60,0x0,0x0,0x35b60,0x35b60},
103 {"Reserved48",0x1,0x1,0x1,0x0,0x0,0x1,0x1},
104 {"Reserved49",0x1,0x1,0x1,0x0,0x0,0x1,0x1},
105 {"Letter Extra",0x1,0x3ae94,0x4a6a0,0x0,0x0,0x3ae94,0x4a6a0},
106 {"Legal Extra",0x1,0x3ae94,0x5d048,0x0,0x0,0x3ae94,0x5d048},
107 {"Tabloid Extra",0x1,0x4a6a0,0x6f9f0,0x0,0x0,0x4a6a0,0x6f9f0},
108 {"A4 Extra",0x1,0x397c2,0x4eb16,0x0,0x0,0x397c2,0x4eb16},
109 {"Letter Transverse",0x1,0x34b5c,0x44368,0x0,0x0,0x34b5c,0x44368},
110 {"A4 Transverse",0x1,0x33450,0x48828,0x0,0x0,0x33450,0x48828},
111 {"Letter Extra Transverse",0x1,0x3ae94,0x4a6a0,0x0,0x0,0x3ae94,0x4a6a0},
112 {"Super A",0x1,0x376b8,0x56ea0,0x0,0x0,0x376b8,0x56ea0},
113 {"Super B",0x1,0x4a768,0x76e58,0x0,0x0,0x4a768,0x76e58},
114 {"Letter Plus",0x1,0x34b5c,0x4eb16,0x0,0x0,0x34b5c,0x4eb16},
115 {"A4 Plus",0x1,0x33450,0x50910,0x0,0x0,0x33450,0x50910},
116 {"A5 Transverse",0x1,0x24220,0x33450,0x0,0x0,0x24220,0x33450},
117 {"B5 (JIS) Transverse",0x1,0x2c6f0,0x3ebe8,0x0,0x0,0x2c6f0,0x3ebe8},
118 {"A3 Extra",0x1,0x4e9d0,0x6ca48,0x0,0x0,0x4e9d0,0x6ca48},
119 {"A5 Extra",0x1,0x2a7b0,0x395f8,0x0,0x0,0x2a7b0,0x395f8},
120 {"B5 (ISO) Extra",0x1,0x31128,0x43620,0x0,0x0,0x31128,0x43620},
121 {"A2",0x1,0x668a0,0x91050,0x0,0x0,0x668a0,0x91050},
122 {"A3 Transverse",0x1,0x48828,0x668a0,0x0,0x0,0x48828,0x668a0},
123 {"A3 Extra Transverse",0x1,0x4e9d0,0x6ca48,0x0,0x0,0x4e9d0,0x6ca48},
124 {"Japanese Double Postcard",0x1,0x30d40,0x24220,0x0,0x0,0x30d40,0x24220},
125 {"A6",0x1,0x19a28,0x24220,0x0,0x0,0x19a28,0x24220},
126 {"Japanese Envelope Kaku #2",0x1,0x3a980,0x510e0,0x0,0x0,0x3a980,0x510e0},
127 {"Japanese Envelope Kaku #3",0x1,0x34bc0,0x43a08,0x0,0x0,0x34bc0,0x43a08},
128 {"Japanese Envelope Chou #3",0x1,0x1d4c0,0x395f8,0x0,0x0,0x1d4c0,0x395f8},
129 {"Japanese Envelope Chou #4",0x1,0x15f90,0x320c8,0x0,0x0,0x15f90,0x320c8},
130 {"Letter Rotated",0x1,0x44368,0x34b5c,0x0,0x0,0x44368,0x34b5c},
131 {"A3 Rotated",0x1,0x668a0,0x48828,0x0,0x0,0x668a0,0x48828},
132 {"A4 Rotated",0x1,0x48828,0x33450,0x0,0x0,0x48828,0x33450},
133 {"A5 Rotated",0x1,0x33450,0x24220,0x0,0x0,0x33450,0x24220},
134 {"B4 (JIS) Rotated",0x1,0x58de0,0x3ebe8,0x0,0x0,0x58de0,0x3ebe8},
135 {"B5 (JIS) Rotated",0x1,0x3ebe8,0x2c6f0,0x0,0x0,0x3ebe8,0x2c6f0},
136 {"Japanese Postcard Rotated",0x1,0x24220,0x186a0,0x0,0x0,0x24220,0x186a0},
137 {"Double Japan Postcard Rotated",0x1,0x24220,0x30d40,0x0,0x0,0x24220,0x30d40},
138 {"A6 Rotated",0x1,0x24220,0x19a28,0x0,0x0,0x24220,0x19a28},
139 {"Japan Envelope Kaku #2 Rotated",0x1,0x510e0,0x3a980,0x0,0x0,0x510e0,0x3a980},
140 {"Japan Envelope Kaku #3 Rotated",0x1,0x43a08,0x34bc0,0x0,0x0,0x43a08, 0x34bc0},
141 {"Japan Envelope Chou #3 Rotated",0x1,0x395f8,0x1d4c0,0x0,0x0,0x395f8,0x1d4c0},
142 {"Japan Envelope Chou #4 Rotated",0x1,0x320c8,0x15f90,0x0,0x0,0x320c8,0x15f90},
143 {"B6 (JIS)",0x1,0x1f400,0x2c6f0,0x0,0x0,0x1f400,0x2c6f0},
144 {"B6 (JIS) Rotated",0x1,0x2c6f0,0x1f400,0x0,0x0,0x2c6f0,0x1f400},
145 {"12x11",0x1,0x4a724,0x443e1,0x0,0x0,0x4a724,0x443e1},
146 {"Japan Envelope You #4",0x1,0x19a28,0x395f8,0x0,0x0,0x19a28,0x395f8},
147 {"Japan Envelope You #4 Rotated",0x1,0x395f8,0x19a28,0x0,0x0,0x395f8,0x19a28},
148 {"PRC 16K",0x1,0x2de60,0x3f7a0,0x0,0x0,0x2de60,0x3f7a0},
149 {"PRC 32K",0x1,0x1fbd0,0x2cec0,0x0,0x0,0x1fbd0,0x2cec0},
150 {"PRC 32K(Big)",0x1,0x222e0,0x318f8,0x0,0x0,0x222e0,0x318f8},
151 {"PRC Envelope #1",0x1,0x18e70,0x28488,0x0,0x0,0x18e70,0x28488},
152 {"PRC Envelope #2",0x1,0x18e70,0x2af80,0x0,0x0,0x18e70,0x2af80},
153 {"PRC Envelope #3",0x1,0x1e848,0x2af80,0x0,0x0,0x1e848,0x2af80},
154 {"PRC Envelope #4",0x1,0x1adb0,0x32c80,0x0,0x0,0x1adb0,0x32c80},
155 {"PRC Envelope #5",0x1,0x1adb0,0x35b60,0x0,0x0,0x1adb0,0x35b60},
156 {"PRC Envelope #6",0x1,0x1d4c0,0x38270,0x0,0x0,0x1d4c0,0x38270},
157 {"PRC Envelope #7",0x1,0x27100,0x38270,0x0,0x0,0x27100,0x38270},
158 {"PRC Envelope #8",0x1,0x1d4c0,0x4b708,0x0,0x0,0x1d4c0,0x4b708},
159 {"PRC Envelope #9",0x1,0x37e88,0x4f1a0,0x0,0x0,0x37e88,0x4f1a0},
160 {"PRC Envelope #10",0x1,0x4f1a0,0x6fd10,0x0,0x0,0x4f1a0,0x6fd10},
161 {"PRC 16K Rotated",0x1,0x3f7a0,0x2de60,0x0,0x0,0x3f7a0,0x2de60},
162 {"PRC 32K Rotated",0x1,0x2cec0,0x1fbd0,0x0,0x0,0x2cec0,0x1fbd0},
163 {"PRC 32K(Big) Rotated",0x1,0x318f8,0x222e0,0x0,0x0,0x318f8,0x222e0},
164 {"PRC Envelope #1 Rotated",0x1,0x28488,0x18e70,0x0,0x0,0x28488,0x18e70},
165 {"PRC Envelope #2 Rotated",0x1,0x2af80,0x18e70,0x0,0x0,0x2af80,0x18e70},
166 {"PRC Envelope #3 Rotated",0x1,0x2af80,0x1e848,0x0,0x0,0x2af80,0x1e848},
167 {"PRC Envelope #4 Rotated",0x1,0x32c80,0x1adb0,0x0,0x0,0x32c80,0x1adb0},
168 {"PRC Envelope #5 Rotated",0x1,0x35b60,0x1adb0,0x0,0x0,0x35b60,0x1adb0},
169 {"PRC Envelope #6 Rotated",0x1,0x38270,0x1d4c0,0x0,0x0,0x38270,0x1d4c0},
170 {"PRC Envelope #7 Rotated",0x1,0x38270,0x27100,0x0,0x0,0x38270,0x27100},
171 {"PRC Envelope #8 Rotated",0x1,0x4b708,0x1d4c0,0x0,0x0,0x4b708,0x1d4c0},
172 {"PRC Envelope #9 Rotated",0x1,0x4f1a0,0x37e88,0x0,0x0,0x4f1a0,0x37e88},
173 {"PRC Envelope #10 Rotated",0x1,0x6fd10,0x4f1a0,0x0,0x0,0x6fd10,0x4f1a0}
176 static BOOL upgrade_to_version_2(void)
178 TDB_DATA kbuf, newkey, dbuf;
180 DEBUG(0,("upgrade_to_version_2: upgrading print tdb's to version 2\n"));
182 for (kbuf = tdb_firstkey(tdb_drivers); kbuf.dptr;
183 newkey = tdb_nextkey(tdb_drivers, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
185 dbuf = tdb_fetch(tdb_drivers, kbuf);
187 if (strncmp(kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) == 0) {
188 DEBUG(0,("upgrade_to_version_2:moving form\n"));
189 if (tdb_store(tdb_forms, kbuf, dbuf, TDB_REPLACE) != 0) {
190 DEBUG(0,("upgrade_to_version_2: failed to move form. Error (%s).\n", tdb_errorstr(tdb_forms)));
193 if (tdb_delete(tdb_drivers, kbuf) != 0) {
194 DEBUG(0,("upgrade_to_version_2: failed to delete form. Error (%s)\n", tdb_errorstr(tdb_drivers)));
199 if (strncmp(kbuf.dptr, PRINTERS_PREFIX, strlen(PRINTERS_PREFIX)) == 0) {
200 DEBUG(0,("upgrade_to_version_2:moving printer\n"));
201 if (tdb_store(tdb_printers, kbuf, dbuf, TDB_REPLACE) != 0) {
202 DEBUG(0,("upgrade_to_version_2: failed to move printer. Error (%s)\n", tdb_errorstr(tdb_printers)));
205 if (tdb_delete(tdb_drivers, kbuf) != 0) {
206 DEBUG(0,("upgrade_to_version_2: failed to delete printer. Error (%s)\n", tdb_errorstr(tdb_drivers)));
211 if (strncmp(kbuf.dptr, SECDESC_PREFIX, strlen(SECDESC_PREFIX)) == 0) {
212 DEBUG(0,("upgrade_to_version_2:moving secdesc\n"));
213 if (tdb_store(tdb_printers, kbuf, dbuf, TDB_REPLACE) != 0) {
214 DEBUG(0,("upgrade_to_version_2: failed to move secdesc. Error (%s)\n", tdb_errorstr(tdb_printers)));
217 if (tdb_delete(tdb_drivers, kbuf) != 0) {
218 DEBUG(0,("upgrade_to_version_2: failed to delete secdesc. Error (%s)\n", tdb_errorstr(tdb_drivers)));
223 SAFE_FREE(dbuf.dptr);
229 /****************************************************************************
230 open the NT printing tdb
231 ****************************************************************************/
232 BOOL nt_printing_init(void)
234 static pid_t local_pid;
235 char *vstring = "INFO/version";
237 if (tdb_drivers && tdb_printers && tdb_forms && local_pid == sys_getpid())
240 tdb_drivers = tdb_open_log(lock_path("ntdrivers.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
242 DEBUG(0,("nt_printing_init: Failed to open nt drivers database %s (%s)\n",
243 lock_path("ntdrivers.tdb"), strerror(errno) ));
247 tdb_printers = tdb_open_log(lock_path("ntprinters.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
249 DEBUG(0,("nt_printing_init: Failed to open nt printers database %s (%s)\n",
250 lock_path("ntprinters.tdb"), strerror(errno) ));
254 tdb_forms = tdb_open_log(lock_path("ntforms.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
256 DEBUG(0,("nt_printing_init: Failed to open nt forms database %s (%s)\n",
257 lock_path("ntforms.tdb"), strerror(errno) ));
261 local_pid = sys_getpid();
263 /* handle a Samba upgrade */
264 tdb_lock_bystring(tdb_drivers, vstring);
265 if (tdb_fetch_int(tdb_drivers, vstring) != NTDRIVERS_DATABASE_VERSION) {
267 if (tdb_fetch_int(tdb_drivers, vstring) == NTDRIVERS_DATABASE_VERSION_1) {
268 if (!upgrade_to_version_2())
271 tdb_traverse(tdb_drivers, tdb_traverse_delete_fn, NULL);
273 tdb_store_int(tdb_drivers, vstring, NTDRIVERS_DATABASE_VERSION);
275 tdb_unlock_bystring(tdb_drivers, vstring);
280 /****************************************************************************
281 get builtin form struct list
282 ****************************************************************************/
283 int get_builtin_ntforms(nt_forms_struct **list)
285 *list = (nt_forms_struct *)memdup(&default_forms[0], sizeof(default_forms));
286 return sizeof(default_forms) / sizeof(default_forms[0]);
289 /****************************************************************************
290 get a builtin form struct
291 ****************************************************************************/
293 BOOL get_a_builtin_ntform(UNISTR2 *uni_formname,nt_forms_struct *form)
297 unistr2_to_ascii(form_name, uni_formname, sizeof(form_name)-1);
298 DEBUGADD(6,("Looking for builtin form %s \n", form_name));
299 count = sizeof(default_forms) / sizeof(default_forms[0]);
300 for (i=0;i<count;i++) {
301 if (strequal(form_name,default_forms[i].name)) {
302 DEBUGADD(6,("Found builtin form %s \n", form_name));
303 memcpy(form,&default_forms[i],sizeof(*form));
311 /****************************************************************************
312 get a form struct list
313 ****************************************************************************/
314 int get_ntforms(nt_forms_struct **list)
316 TDB_DATA kbuf, newkey, dbuf;
318 nt_forms_struct form;
323 for (kbuf = tdb_firstkey(tdb_forms);
325 newkey = tdb_nextkey(tdb_forms, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
326 if (strncmp(kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) != 0) continue;
328 dbuf = tdb_fetch(tdb_forms, kbuf);
329 if (!dbuf.dptr) continue;
331 fstrcpy(form.name, kbuf.dptr+strlen(FORMS_PREFIX));
332 ret = tdb_unpack(dbuf.dptr, dbuf.dsize, "dddddddd",
333 &i, &form.flag, &form.width, &form.length, &form.left,
334 &form.top, &form.right, &form.bottom);
335 SAFE_FREE(dbuf.dptr);
336 if (ret != dbuf.dsize) continue;
338 tl = Realloc(*list, sizeof(nt_forms_struct)*(n+1));
340 DEBUG(0,("get_ntforms: Realloc fail.\n"));
352 /****************************************************************************
353 write a form struct list
354 ****************************************************************************/
355 int write_ntforms(nt_forms_struct **list, int number)
362 for (i=0;i<number;i++) {
363 /* save index, so list is rebuilt in correct order */
364 len = tdb_pack(buf, sizeof(buf), "dddddddd",
365 i, (*list)[i].flag, (*list)[i].width, (*list)[i].length,
366 (*list)[i].left, (*list)[i].top, (*list)[i].right,
368 if (len > sizeof(buf)) break;
369 slprintf(key, sizeof(key)-1, "%s%s", FORMS_PREFIX, (*list)[i].name);
370 kbuf.dsize = strlen(key)+1;
374 if (tdb_store(tdb_forms, kbuf, dbuf, TDB_REPLACE) != 0) break;
380 /****************************************************************************
381 add a form struct at the end of the list
382 ****************************************************************************/
383 BOOL add_a_form(nt_forms_struct **list, const FORM *form, int *count)
391 * NT tries to add forms even when
392 * they are already in the base
393 * only update the values if already present
398 unistr2_to_ascii(form_name, &form->name, sizeof(form_name)-1);
399 for (n=0; n<*count; n++) {
400 if (!strncmp((*list)[n].name, form_name, strlen(form_name))) {
401 DEBUG(103, ("NT workaround, [%s] already exists\n", form_name));
408 if((tl=Realloc(*list, (n+1)*sizeof(nt_forms_struct))) == NULL) {
409 DEBUG(0,("add_a_form: failed to enlarge forms list!\n"));
413 unistr2_to_ascii((*list)[n].name, &form->name, sizeof((*list)[n].name)-1);
417 (*list)[n].flag=form->flags;
418 (*list)[n].width=form->size_x;
419 (*list)[n].length=form->size_y;
420 (*list)[n].left=form->left;
421 (*list)[n].top=form->top;
422 (*list)[n].right=form->right;
423 (*list)[n].bottom=form->bottom;
428 /****************************************************************************
429 delete a named form struct
430 ****************************************************************************/
431 BOOL delete_a_form(nt_forms_struct **list, UNISTR2 *del_name, int *count, WERROR *ret)
440 unistr2_to_ascii(form_name, del_name, sizeof(form_name)-1);
442 for (n=0; n<*count; n++) {
443 if (!strncmp((*list)[n].name, form_name, strlen(form_name))) {
444 DEBUG(103, ("delete_a_form, [%s] in list\n", form_name));
450 DEBUG(10,("delete_a_form, [%s] not found\n", form_name));
451 *ret = WERR_INVALID_PARAM;
455 slprintf(key, sizeof(key)-1, "%s%s", FORMS_PREFIX, (*list)[n].name);
456 kbuf.dsize = strlen(key)+1;
458 if (tdb_delete(tdb_forms, kbuf) != 0) {
466 /****************************************************************************
468 ****************************************************************************/
469 void update_a_form(nt_forms_struct **list, const FORM *form, int count)
473 unistr2_to_ascii(form_name, &(form->name), sizeof(form_name)-1);
475 DEBUG(106, ("[%s]\n", form_name));
476 for (n=0; n<count; n++)
478 DEBUGADD(106, ("n [%d]:[%s]\n", n, (*list)[n].name));
479 if (!strncmp((*list)[n].name, form_name, strlen(form_name)))
483 if (n==count) return;
485 (*list)[n].flag=form->flags;
486 (*list)[n].width=form->size_x;
487 (*list)[n].length=form->size_y;
488 (*list)[n].left=form->left;
489 (*list)[n].top=form->top;
490 (*list)[n].right=form->right;
491 (*list)[n].bottom=form->bottom;
494 /****************************************************************************
495 get the nt drivers list
497 traverse the database and look-up the matching names
498 ****************************************************************************/
499 int get_ntdrivers(fstring **list, char *architecture, uint32 version)
505 TDB_DATA kbuf, newkey;
507 get_short_archi(short_archi, architecture);
508 slprintf(key, sizeof(key)-1, "%s%s/%d/", DRIVERS_PREFIX, short_archi, version);
510 for (kbuf = tdb_firstkey(tdb_drivers);
512 newkey = tdb_nextkey(tdb_drivers, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
513 if (strncmp(kbuf.dptr, key, strlen(key)) != 0) continue;
515 if((fl = Realloc(*list, sizeof(fstring)*(total+1))) == NULL) {
516 DEBUG(0,("get_ntdrivers: failed to enlarge list!\n"));
521 fstrcpy((*list)[total], kbuf.dptr+strlen(key));
528 /****************************************************************************
529 function to do the mapping between the long architecture name and
531 ****************************************************************************/
532 BOOL get_short_archi(char *short_archi, char *long_archi)
539 struct table archi_table[]=
541 {"Windows 4.0", "WIN40" },
542 {"Windows NT x86", "W32X86" },
543 {"Windows NT R4000", "W32MIPS" },
544 {"Windows NT Alpha_AXP", "W32ALPHA" },
545 {"Windows NT PowerPC", "W32PPC" },
551 DEBUG(107,("Getting architecture dependant directory\n"));
554 } while ( (archi_table[i].long_archi!=NULL ) &&
555 StrCaseCmp(long_archi, archi_table[i].long_archi) );
557 if (archi_table[i].long_archi==NULL) {
558 DEBUGADD(107,("Unknown architecture [%s] !\n", long_archi));
562 StrnCpy (short_archi, archi_table[i].short_archi, strlen(archi_table[i].short_archi));
564 DEBUGADD(108,("index: [%d]\n", i));
565 DEBUGADD(108,("long architecture: [%s]\n", long_archi));
566 DEBUGADD(108,("short architecture: [%s]\n", short_archi));
571 /****************************************************************************
572 Version information in Microsoft files is held in a VS_VERSION_INFO structure.
573 There are two case to be covered here: PE (Portable Executable) and NE (New
574 Executable) files. Both files support the same INFO structure, but PE files
575 store the signature in unicode, and NE files store it as !unicode.
576 ****************************************************************************/
577 static BOOL get_file_version(files_struct *fsp, char *fname,uint32 *major,
584 if ((buf=malloc(PE_HEADER_SIZE)) == NULL) {
585 DEBUG(0,("get_file_version: PE file [%s] PE Header malloc failed bytes = %d\n",
586 fname, PE_HEADER_SIZE));
590 /* Note: DOS_HEADER_SIZE < malloc'ed PE_HEADER_SIZE */
591 if ((byte_count = vfs_read_data(fsp, buf, DOS_HEADER_SIZE)) < DOS_HEADER_SIZE) {
592 DEBUG(3,("get_file_version: File [%s] DOS header too short, bytes read = %d\n",
594 goto no_version_info;
597 /* Is this really a DOS header? */
598 if (SVAL(buf,DOS_HEADER_MAGIC_OFFSET) != DOS_HEADER_MAGIC) {
599 DEBUG(6,("get_file_version: File [%s] bad DOS magic = 0x%x\n",
600 fname, SVAL(buf,DOS_HEADER_MAGIC_OFFSET)));
601 goto no_version_info;
604 /* Skip OEM header (if any) and the DOS stub to start of Windows header */
605 if (fsp->conn->vfs_ops.lseek(fsp, fsp->fd, SVAL(buf,DOS_HEADER_LFANEW_OFFSET), SEEK_SET) == (SMB_OFF_T)-1) {
606 DEBUG(3,("get_file_version: File [%s] too short, errno = %d\n",
608 /* Assume this isn't an error... the file just looks sort of like a PE/NE file */
609 goto no_version_info;
612 if ((byte_count = vfs_read_data(fsp, buf, PE_HEADER_SIZE)) < PE_HEADER_SIZE) {
613 DEBUG(3,("get_file_version: File [%s] Windows header too short, bytes read = %d\n",
615 /* Assume this isn't an error... the file just looks sort of like a PE/NE file */
616 goto no_version_info;
619 /* The header may be a PE (Portable Executable) or an NE (New Executable) */
620 if (IVAL(buf,PE_HEADER_SIGNATURE_OFFSET) == PE_HEADER_SIGNATURE) {
622 int section_table_bytes;
624 if (SVAL(buf,PE_HEADER_MACHINE_OFFSET) != PE_HEADER_MACHINE_I386) {
625 DEBUG(3,("get_file_version: PE file [%s] wrong machine = 0x%x\n",
626 fname, SVAL(buf,PE_HEADER_MACHINE_OFFSET)));
627 /* At this point, we assume the file is in error. It still could be somthing
628 * else besides a PE file, but it unlikely at this point.
633 /* get the section table */
634 num_sections = SVAL(buf,PE_HEADER_NUMBER_OF_SECTIONS);
635 section_table_bytes = num_sections * PE_HEADER_SECT_HEADER_SIZE;
637 if ((buf=malloc(section_table_bytes)) == NULL) {
638 DEBUG(0,("get_file_version: PE file [%s] section table malloc failed bytes = %d\n",
639 fname, section_table_bytes));
643 if ((byte_count = vfs_read_data(fsp, buf, section_table_bytes)) < section_table_bytes) {
644 DEBUG(3,("get_file_version: PE file [%s] Section header too short, bytes read = %d\n",
649 /* Iterate the section table looking for the resource section ".rsrc" */
650 for (i = 0; i < num_sections; i++) {
651 int sec_offset = i * PE_HEADER_SECT_HEADER_SIZE;
653 if (strcmp(".rsrc", &buf[sec_offset+PE_HEADER_SECT_NAME_OFFSET]) == 0) {
654 int section_pos = IVAL(buf,sec_offset+PE_HEADER_SECT_PTR_DATA_OFFSET);
655 int section_bytes = IVAL(buf,sec_offset+PE_HEADER_SECT_SIZE_DATA_OFFSET);
658 if ((buf=malloc(section_bytes)) == NULL) {
659 DEBUG(0,("get_file_version: PE file [%s] version malloc failed bytes = %d\n",
660 fname, section_bytes));
664 /* Seek to the start of the .rsrc section info */
665 if (fsp->conn->vfs_ops.lseek(fsp, fsp->fd, section_pos, SEEK_SET) == (SMB_OFF_T)-1) {
666 DEBUG(3,("get_file_version: PE file [%s] too short for section info, errno = %d\n",
671 if ((byte_count = vfs_read_data(fsp, buf, section_bytes)) < section_bytes) {
672 DEBUG(3,("get_file_version: PE file [%s] .rsrc section too short, bytes read = %d\n",
677 for (i=0; i<section_bytes-VS_VERSION_INFO_UNICODE_SIZE; i++) {
678 /* Scan for 1st 3 unicoded bytes followed by word aligned magic value */
679 if (buf[i] == 'V' && buf[i+1] == '\0' && buf[i+2] == 'S') {
680 /* Align to next long address */
681 int pos = (i + sizeof(VS_SIGNATURE)*2 + 3) & 0xfffffffc;
683 if (IVAL(buf,pos) == VS_MAGIC_VALUE) {
684 *major = IVAL(buf,pos+VS_MAJOR_OFFSET);
685 *minor = IVAL(buf,pos+VS_MINOR_OFFSET);
687 DEBUG(6,("get_file_version: PE file [%s] Version = %08x:%08x (%d.%d.%d.%d)\n",
688 fname, *major, *minor,
689 (*major>>16)&0xffff, *major&0xffff,
690 (*minor>>16)&0xffff, *minor&0xffff));
699 /* Version info not found, fall back to origin date/time */
700 DEBUG(10,("get_file_version: PE file [%s] has no version info\n", fname));
704 } else if (SVAL(buf,NE_HEADER_SIGNATURE_OFFSET) == NE_HEADER_SIGNATURE) {
705 if (CVAL(buf,NE_HEADER_TARGET_OS_OFFSET) != NE_HEADER_TARGOS_WIN ) {
706 DEBUG(3,("get_file_version: NE file [%s] wrong target OS = 0x%x\n",
707 fname, CVAL(buf,NE_HEADER_TARGET_OS_OFFSET)));
708 /* At this point, we assume the file is in error. It still could be somthing
709 * else besides a NE file, but it unlikely at this point. */
713 /* Allocate a bit more space to speed up things */
715 if ((buf=malloc(VS_NE_BUF_SIZE)) == NULL) {
716 DEBUG(0,("get_file_version: NE file [%s] malloc failed bytes = %d\n",
717 fname, PE_HEADER_SIZE));
721 /* This is a HACK! I got tired of trying to sort through the messy
722 * 'NE' file format. If anyone wants to clean this up please have at
723 * it, but this works. 'NE' files will eventually fade away. JRR */
724 while((byte_count = vfs_read_data(fsp, buf, VS_NE_BUF_SIZE)) > 0) {
725 /* Cover case that should not occur in a well formed 'NE' .dll file */
726 if (byte_count-VS_VERSION_INFO_SIZE <= 0) break;
728 for(i=0; i<byte_count; i++) {
729 /* Fast skip past data that can't possibly match */
730 if (buf[i] != 'V') continue;
732 /* Potential match data crosses buf boundry, move it to beginning
733 * of buf, and fill the buf with as much as it will hold. */
734 if (i>byte_count-VS_VERSION_INFO_SIZE) {
737 memcpy(buf, &buf[i], byte_count-i);
738 if ((bc = vfs_read_data(fsp, &buf[byte_count-i], VS_NE_BUF_SIZE-
739 (byte_count-i))) < 0) {
741 DEBUG(0,("get_file_version: NE file [%s] Read error, errno=%d\n",
746 byte_count = bc + (byte_count - i);
747 if (byte_count<VS_VERSION_INFO_SIZE) break;
752 /* Check that the full signature string and the magic number that
753 * follows exist (not a perfect solution, but the chances that this
754 * occurs in code is, well, remote. Yes I know I'm comparing the 'V'
755 * twice, as it is simpler to read the code. */
756 if (strcmp(&buf[i], VS_SIGNATURE) == 0) {
757 /* Compute skip alignment to next long address */
758 int skip = -(fsp->conn->vfs_ops.lseek(fsp, fsp->fd, 0, SEEK_CUR) - (byte_count - i) +
759 sizeof(VS_SIGNATURE)) & 3;
760 if (IVAL(buf,i+sizeof(VS_SIGNATURE)+skip) != 0xfeef04bd) continue;
762 *major = IVAL(buf,i+sizeof(VS_SIGNATURE)+skip+VS_MAJOR_OFFSET);
763 *minor = IVAL(buf,i+sizeof(VS_SIGNATURE)+skip+VS_MINOR_OFFSET);
764 DEBUG(6,("get_file_version: NE file [%s] Version = %08x:%08x (%d.%d.%d.%d)\n",
765 fname, *major, *minor,
766 (*major>>16)&0xffff, *major&0xffff,
767 (*minor>>16)&0xffff, *minor&0xffff));
774 /* Version info not found, fall back to origin date/time */
775 DEBUG(0,("get_file_version: NE file [%s] Version info not found\n", fname));
780 /* Assume this isn't an error... the file just looks sort of like a PE/NE file */
781 DEBUG(3,("get_file_version: File [%s] unknown file format, signature = 0x%x\n",
782 fname, IVAL(buf,PE_HEADER_SIGNATURE_OFFSET)));
793 /****************************************************************************
794 Drivers for Microsoft systems contain multiple files. Often, multiple drivers
795 share one or more files. During the MS installation process files are checked
796 to insure that only a newer version of a shared file is installed over an
797 older version. There are several possibilities for this comparison. If there
798 is no previous version, the new one is newer (obviously). If either file is
799 missing the version info structure, compare the creation date (on Unix use
800 the modification date). Otherwise chose the numerically larger version number.
801 ****************************************************************************/
802 static int file_version_is_newer(connection_struct *conn, fstring new_file,
805 BOOL use_version = True;
810 time_t new_create_time;
814 time_t old_create_time;
818 files_struct *fsp = NULL;
820 SMB_STRUCT_STAT stat_buf;
824 ZERO_STRUCT(stat_buf);
825 new_create_time = (time_t)0;
826 old_create_time = (time_t)0;
828 /* Get file version info (if available) for previous file (if it exists) */
829 pstrcpy(filepath, old_file);
831 unix_convert(filepath,conn,NULL,&bad_path,&stat_buf);
833 fsp = open_file_shared(conn, filepath, &stat_buf,
834 SET_OPEN_MODE(DOS_OPEN_RDONLY),
835 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
836 0, 0, &access_mode, &action);
838 /* Old file not found, so by definition new file is in fact newer */
839 DEBUG(10,("file_version_is_newer: Can't open old file [%s], errno = %d\n",
844 int ret = get_file_version(fsp, old_file, &old_major, &old_minor);
845 if (ret == -1) goto error_exit;
848 DEBUG(6,("file_version_is_newer: Version info not found [%s], use mod time\n",
851 if (fsp->conn->vfs_ops.fstat(fsp, fsp->fd, &st) == -1) goto error_exit;
852 old_create_time = st.st_mtime;
853 DEBUGADD(6,("file_version_is_newer: mod time = %ld sec\n", old_create_time));
856 close_file(fsp, True);
858 /* Get file version info (if available) for new file */
859 pstrcpy(filepath, new_file);
860 unix_convert(filepath,conn,NULL,&bad_path,&stat_buf);
862 fsp = open_file_shared(conn, filepath, &stat_buf,
863 SET_OPEN_MODE(DOS_OPEN_RDONLY),
864 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
865 0, 0, &access_mode, &action);
867 /* New file not found, this shouldn't occur if the caller did its job */
868 DEBUG(3,("file_version_is_newer: Can't open new file [%s], errno = %d\n",
873 int ret = get_file_version(fsp, new_file, &new_major, &new_minor);
874 if (ret == -1) goto error_exit;
877 DEBUG(6,("file_version_is_newer: Version info not found [%s], use mod time\n",
880 if (fsp->conn->vfs_ops.fstat(fsp, fsp->fd, &st) == -1) goto error_exit;
881 new_create_time = st.st_mtime;
882 DEBUGADD(6,("file_version_is_newer: mod time = %ld sec\n", new_create_time));
885 close_file(fsp, True);
888 /* Compare versions and choose the larger version number */
889 if (new_major > old_major ||
890 (new_major == old_major && new_minor > old_minor)) {
892 DEBUG(6,("file_version_is_newer: Replacing [%s] with [%s]\n", old_file, new_file));
896 DEBUG(6,("file_version_is_newer: Leaving [%s] unchanged\n", old_file));
901 /* Compare modification time/dates and choose the newest time/date */
902 if (new_create_time > old_create_time) {
903 DEBUG(6,("file_version_is_newer: Replacing [%s] with [%s]\n", old_file, new_file));
907 DEBUG(6,("file_version_is_newer: Leaving [%s] unchanged\n", old_file));
914 close_file(fsp, True);
918 /****************************************************************************
919 Determine the correct cVersion associated with an architecture and driver
920 ****************************************************************************/
921 static uint32 get_correct_cversion(fstring architecture, fstring driverpath_in,
922 struct current_user *user, WERROR *perr)
930 files_struct *fsp = NULL;
933 connection_struct *conn;
937 *perr = WERR_INVALID_PARAM;
939 /* If architecture is Windows 95/98/ME, the version is always 0. */
940 if (strcmp(architecture, "WIN40") == 0) {
941 DEBUG(10,("get_correct_cversion: Driver is Win9x, cversion = 0\n"));
946 /* connect to the print$ share under the same account as the user connected to the rpc pipe */
947 /* Null password is ok - we are already an authenticated user... */
948 null_pw = data_blob(NULL, 0);
951 conn = make_connection("print$", null_pw, "A:", user->vuid, &nt_status);
955 DEBUG(0,("get_correct_cversion: Unable to connect\n"));
956 *perr = ntstatus_to_werror(nt_status);
960 /* We are temporarily becoming the connection user. */
961 if (!become_user(conn, conn->vuid)) {
962 DEBUG(0,("get_correct_cversion: Can't become user!\n"));
963 *perr = WERR_ACCESS_DENIED;
967 /* Open the driver file (Portable Executable format) and determine the
968 * deriver the cversion. */
969 slprintf(driverpath, sizeof(driverpath)-1, "%s/%s", architecture, driverpath_in);
971 unix_convert(driverpath,conn,NULL,&bad_path,&st);
973 fsp = open_file_shared(conn, driverpath, &st,
974 SET_OPEN_MODE(DOS_OPEN_RDONLY),
975 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
976 0, 0, &access_mode, &action);
978 DEBUG(3,("get_correct_cversion: Can't open file [%s], errno = %d\n",
980 *perr = WERR_ACCESS_DENIED;
986 int ret = get_file_version(fsp, driverpath, &major, &minor);
987 if (ret == -1) goto error_exit;
990 DEBUG(6,("get_correct_cversion: Version info not found [%s]\n", driverpath));
995 * This is a Microsoft'ism. See references in MSDN to VER_FILEVERSION
996 * for more details. Version in this case is not just the version of the
997 * file, but the version in the sense of kernal mode (2) vs. user mode
998 * (3) drivers. Other bits of the version fields are the version info.
1001 cversion = major & 0x0000ffff;
1003 case 2: /* WinNT drivers */
1004 case 3: /* Win2K drivers */
1008 DEBUG(6,("get_correct_cversion: cversion invalid [%s] cversion = %d\n",
1009 driverpath, cversion));
1013 DEBUG(10,("get_correct_cversion: Version info found [%s] major = 0x%x minor = 0x%x\n",
1014 driverpath, major, minor));
1017 DEBUG(10,("get_correct_cversion: Driver file [%s] cversion = %d\n",
1018 driverpath, cversion));
1020 close_file(fsp, True);
1021 close_cnum(conn, user->vuid);
1029 close_file(fsp, True);
1031 close_cnum(conn, user->vuid);
1036 /****************************************************************************
1037 ****************************************************************************/
1038 static WERROR clean_up_driver_struct_level_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver,
1039 struct current_user *user)
1041 fstring architecture;
1047 /* clean up the driver name.
1048 * we can get .\driver.dll
1049 * or worse c:\windows\system\driver.dll !
1051 /* using an intermediate string to not have overlaping memcpy()'s */
1052 if ((p = strrchr(driver->driverpath,'\\')) != NULL) {
1053 fstrcpy(new_name, p+1);
1054 fstrcpy(driver->driverpath, new_name);
1057 if ((p = strrchr(driver->datafile,'\\')) != NULL) {
1058 fstrcpy(new_name, p+1);
1059 fstrcpy(driver->datafile, new_name);
1062 if ((p = strrchr(driver->configfile,'\\')) != NULL) {
1063 fstrcpy(new_name, p+1);
1064 fstrcpy(driver->configfile, new_name);
1067 if ((p = strrchr(driver->helpfile,'\\')) != NULL) {
1068 fstrcpy(new_name, p+1);
1069 fstrcpy(driver->helpfile, new_name);
1072 if (driver->dependentfiles) {
1073 for (i=0; *driver->dependentfiles[i]; i++) {
1074 if ((p = strrchr(driver->dependentfiles[i],'\\')) != NULL) {
1075 fstrcpy(new_name, p+1);
1076 fstrcpy(driver->dependentfiles[i], new_name);
1081 get_short_archi(architecture, driver->environment);
1083 /* jfm:7/16/2000 the client always sends the cversion=0.
1084 * The server should check which version the driver is by reading
1085 * the PE header of driver->driverpath.
1087 * For Windows 95/98 the version is 0 (so the value sent is correct)
1088 * For Windows NT (the architecture doesn't matter)
1089 * NT 3.1: cversion=0
1090 * NT 3.5/3.51: cversion=1
1094 if ((driver->cversion = get_correct_cversion( architecture,
1095 driver->driverpath, user, &err)) == -1)
1101 /****************************************************************************
1102 ****************************************************************************/
1103 static WERROR clean_up_driver_struct_level_6(NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver,
1104 struct current_user *user)
1106 fstring architecture;
1112 /* clean up the driver name.
1113 * we can get .\driver.dll
1114 * or worse c:\windows\system\driver.dll !
1116 /* using an intermediate string to not have overlaping memcpy()'s */
1117 if ((p = strrchr(driver->driverpath,'\\')) != NULL) {
1118 fstrcpy(new_name, p+1);
1119 fstrcpy(driver->driverpath, new_name);
1122 if ((p = strrchr(driver->datafile,'\\')) != NULL) {
1123 fstrcpy(new_name, p+1);
1124 fstrcpy(driver->datafile, new_name);
1127 if ((p = strrchr(driver->configfile,'\\')) != NULL) {
1128 fstrcpy(new_name, p+1);
1129 fstrcpy(driver->configfile, new_name);
1132 if ((p = strrchr(driver->helpfile,'\\')) != NULL) {
1133 fstrcpy(new_name, p+1);
1134 fstrcpy(driver->helpfile, new_name);
1137 if (driver->dependentfiles) {
1138 for (i=0; *driver->dependentfiles[i]; i++) {
1139 if ((p = strrchr(driver->dependentfiles[i],'\\')) != NULL) {
1140 fstrcpy(new_name, p+1);
1141 fstrcpy(driver->dependentfiles[i], new_name);
1146 get_short_archi(architecture, driver->environment);
1148 /* jfm:7/16/2000 the client always sends the cversion=0.
1149 * The server should check which version the driver is by reading
1150 * the PE header of driver->driverpath.
1152 * For Windows 95/98 the version is 0 (so the value sent is correct)
1153 * For Windows NT (the architecture doesn't matter)
1154 * NT 3.1: cversion=0
1155 * NT 3.5/3.51: cversion=1
1159 if ((driver->version = get_correct_cversion(architecture,
1160 driver->driverpath, user, &err)) == -1)
1166 /****************************************************************************
1167 ****************************************************************************/
1168 WERROR clean_up_driver_struct(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract,
1169 uint32 level, struct current_user *user)
1174 NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver;
1175 driver=driver_abstract.info_3;
1176 return clean_up_driver_struct_level_3(driver, user);
1180 NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver;
1181 driver=driver_abstract.info_6;
1182 return clean_up_driver_struct_level_6(driver, user);
1185 return WERR_INVALID_PARAM;
1189 /****************************************************************************
1190 This function sucks and should be replaced. JRA.
1191 ****************************************************************************/
1193 static void convert_level_6_to_level3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *dst, NT_PRINTER_DRIVER_INFO_LEVEL_6 *src)
1195 dst->cversion = src->version;
1197 fstrcpy( dst->name, src->name);
1198 fstrcpy( dst->environment, src->environment);
1199 fstrcpy( dst->driverpath, src->driverpath);
1200 fstrcpy( dst->datafile, src->datafile);
1201 fstrcpy( dst->configfile, src->configfile);
1202 fstrcpy( dst->helpfile, src->helpfile);
1203 fstrcpy( dst->monitorname, src->monitorname);
1204 fstrcpy( dst->defaultdatatype, src->defaultdatatype);
1205 dst->dependentfiles = src->dependentfiles;
1208 #if 0 /* Debugging function */
1210 static char* ffmt(unsigned char *c){
1212 static char ffmt_str[17];
1214 for (i=0; i<16; i++) {
1215 if ((c[i] < ' ') || (c[i] > '~'))
1226 /****************************************************************************
1227 ****************************************************************************/
1228 BOOL move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract, uint32 level,
1229 struct current_user *user, WERROR *perr)
1231 NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver;
1232 NT_PRINTER_DRIVER_INFO_LEVEL_3 converted_driver;
1233 fstring architecture;
1238 connection_struct *conn;
1246 driver=driver_abstract.info_3;
1247 else if (level==6) {
1248 convert_level_6_to_level3(&converted_driver, driver_abstract.info_6);
1249 driver = &converted_driver;
1251 DEBUG(0,("move_driver_to_download_area: Unknown info level (%u)\n", (unsigned int)level ));
1255 get_short_archi(architecture, driver->environment);
1257 /* connect to the print$ share under the same account as the user connected to the rpc pipe */
1258 /* Null password is ok - we are already an authenticated user... */
1259 null_pw = data_blob(NULL, 0);
1260 conn = make_connection("print$", null_pw, "A:", user->vuid, &nt_status);
1263 DEBUG(0,("move_driver_to_download_area: Unable to connect\n"));
1264 *perr = ntstatus_to_werror(nt_status);
1269 * Save who we are - we are temporarily becoming the connection user.
1274 if (!become_user(conn, conn->vuid)) {
1275 DEBUG(0,("move_driver_to_download_area: Can't become user!\n"));
1281 * make the directories version and version\driver_name
1282 * under the architecture directory.
1284 DEBUG(5,("Creating first directory\n"));
1285 slprintf(new_dir, sizeof(new_dir)-1, "%s/%d", architecture, driver->cversion);
1286 mkdir_internal(conn, new_dir);
1288 /* For each driver file, archi\filexxx.yyy, if there is a duplicate file
1289 * listed for this driver which has already been moved, skip it (note:
1290 * drivers may list the same file name several times. Then check if the
1291 * file already exists in archi\cversion\, if so, check that the version
1292 * info (or time stamps if version info is unavailable) is newer (or the
1293 * date is later). If it is, move it to archi\cversion\filexxx.yyy.
1294 * Otherwise, delete the file.
1296 * If a file is not moved to archi\cversion\ because of an error, all the
1297 * rest of the 'unmoved' driver files are removed from archi\. If one or
1298 * more of the driver's files was already moved to archi\cversion\, it
1299 * potentially leaves the driver in a partially updated state. Version
1300 * trauma will most likely occur if an client attempts to use any printer
1301 * bound to the driver. Perhaps a rewrite to make sure the moves can be
1302 * done is appropriate... later JRR
1305 DEBUG(5,("Moving files now !\n"));
1307 if (driver->driverpath && strlen(driver->driverpath)) {
1308 slprintf(new_name, sizeof(new_name)-1, "%s/%s", architecture, driver->driverpath);
1309 slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->driverpath);
1310 if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
1312 status = rename_internals(conn, new_name, old_name, True);
1313 if (!NT_STATUS_IS_OK(status)) {
1314 DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
1315 new_name, old_name));
1316 *perr = ntstatus_to_werror(status);
1317 unlink_internals(conn, 0, new_name);
1322 unlink_internals(conn, 0, new_name);
1325 if (driver->datafile && strlen(driver->datafile)) {
1326 if (!strequal(driver->datafile, driver->driverpath)) {
1327 slprintf(new_name, sizeof(new_name)-1, "%s/%s", architecture, driver->datafile);
1328 slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->datafile);
1329 if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
1331 status = rename_internals(conn, new_name, old_name, True);
1332 if (!NT_STATUS_IS_OK(status)) {
1333 DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
1334 new_name, old_name));
1335 *perr = ntstatus_to_werror(status);
1336 unlink_internals(conn, 0, new_name);
1341 unlink_internals(conn, 0, new_name);
1345 if (driver->configfile && strlen(driver->configfile)) {
1346 if (!strequal(driver->configfile, driver->driverpath) &&
1347 !strequal(driver->configfile, driver->datafile)) {
1348 slprintf(new_name, sizeof(new_name)-1, "%s/%s", architecture, driver->configfile);
1349 slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->configfile);
1350 if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
1352 status = rename_internals(conn, new_name, old_name, True);
1353 if (!NT_STATUS_IS_OK(status)) {
1354 DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
1355 new_name, old_name));
1356 *perr = ntstatus_to_werror(status);
1357 unlink_internals(conn, 0, new_name);
1362 unlink_internals(conn, 0, new_name);
1366 if (driver->helpfile && strlen(driver->helpfile)) {
1367 if (!strequal(driver->helpfile, driver->driverpath) &&
1368 !strequal(driver->helpfile, driver->datafile) &&
1369 !strequal(driver->helpfile, driver->configfile)) {
1370 slprintf(new_name, sizeof(new_name)-1, "%s/%s", architecture, driver->helpfile);
1371 slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->helpfile);
1372 if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
1374 status = rename_internals(conn, new_name, old_name, True);
1375 if (!NT_STATUS_IS_OK(status)) {
1376 DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
1377 new_name, old_name));
1378 *perr = ntstatus_to_werror(status);
1379 unlink_internals(conn, 0, new_name);
1384 unlink_internals(conn, 0, new_name);
1388 if (driver->dependentfiles) {
1389 for (i=0; *driver->dependentfiles[i]; i++) {
1390 if (!strequal(driver->dependentfiles[i], driver->driverpath) &&
1391 !strequal(driver->dependentfiles[i], driver->datafile) &&
1392 !strequal(driver->dependentfiles[i], driver->configfile) &&
1393 !strequal(driver->dependentfiles[i], driver->helpfile)) {
1395 for (j=0; j < i; j++) {
1396 if (strequal(driver->dependentfiles[i], driver->dependentfiles[j])) {
1401 slprintf(new_name, sizeof(new_name)-1, "%s/%s", architecture, driver->dependentfiles[i]);
1402 slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->dependentfiles[i]);
1403 if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
1405 status = rename_internals(conn, new_name, old_name, True);
1406 if (!NT_STATUS_IS_OK(status)) {
1407 DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
1408 new_name, old_name));
1409 *perr = ntstatus_to_werror(status);
1410 unlink_internals(conn, 0, new_name);
1415 unlink_internals(conn, 0, new_name);
1421 close_cnum(conn, user->vuid);
1424 return ver == -1 ? False : True;
1427 /****************************************************************************
1428 ****************************************************************************/
1429 static uint32 add_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver)
1432 fstring architecture;
1438 TDB_DATA kbuf, dbuf;
1440 get_short_archi(architecture, driver->environment);
1442 /* The names are relative. We store them in the form: \print$\arch\version\driver.xxx
1443 * \\server is added in the rpc server layer.
1444 * It does make sense to NOT store the server's name in the printer TDB.
1447 slprintf(directory, sizeof(directory)-1, "\\print$\\%s\\%d\\", architecture, driver->cversion);
1449 /* .inf files do not always list a file for each of the four standard files.
1450 * Don't prepend a path to a null filename, or client claims:
1451 * "The server on which the printer resides does not have a suitable
1452 * <printer driver name> printer driver installed. Click OK if you
1453 * wish to install the driver on your local machine."
1455 if (strlen(driver->driverpath)) {
1456 fstrcpy(temp_name, driver->driverpath);
1457 slprintf(driver->driverpath, sizeof(driver->driverpath)-1, "%s%s", directory, temp_name);
1460 if (strlen(driver->datafile)) {
1461 fstrcpy(temp_name, driver->datafile);
1462 slprintf(driver->datafile, sizeof(driver->datafile)-1, "%s%s", directory, temp_name);
1465 if (strlen(driver->configfile)) {
1466 fstrcpy(temp_name, driver->configfile);
1467 slprintf(driver->configfile, sizeof(driver->configfile)-1, "%s%s", directory, temp_name);
1470 if (strlen(driver->helpfile)) {
1471 fstrcpy(temp_name, driver->helpfile);
1472 slprintf(driver->helpfile, sizeof(driver->helpfile)-1, "%s%s", directory, temp_name);
1475 if (driver->dependentfiles) {
1476 for (i=0; *driver->dependentfiles[i]; i++) {
1477 fstrcpy(temp_name, driver->dependentfiles[i]);
1478 slprintf(driver->dependentfiles[i], sizeof(driver->dependentfiles[i])-1, "%s%s", directory, temp_name);
1482 slprintf(key, sizeof(key)-1, "%s%s/%d/%s", DRIVERS_PREFIX, architecture, driver->cversion, driver->name);
1484 DEBUG(5,("add_a_printer_driver_3: Adding driver with key %s\n", key ));
1491 len += tdb_pack(buf+len, buflen-len, "dffffffff",
1494 driver->environment,
1499 driver->monitorname,
1500 driver->defaultdatatype);
1502 if (driver->dependentfiles) {
1503 for (i=0; *driver->dependentfiles[i]; i++) {
1504 len += tdb_pack(buf+len, buflen-len, "f",
1505 driver->dependentfiles[i]);
1509 if (len != buflen) {
1512 tb = (char *)Realloc(buf, len);
1514 DEBUG(0,("add_a_printer_driver_3: failed to enlarge buffer\n!"));
1525 kbuf.dsize = strlen(key)+1;
1529 ret = tdb_store(tdb_drivers, kbuf, dbuf, TDB_REPLACE);
1533 DEBUG(0,("add_a_printer_driver_3: Adding driver with key %s failed.\n", key ));
1539 /****************************************************************************
1540 ****************************************************************************/
1541 static uint32 add_a_printer_driver_6(NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver)
1543 NT_PRINTER_DRIVER_INFO_LEVEL_3 info3;
1546 info3.cversion = driver->version;
1547 fstrcpy(info3.name,driver->name);
1548 fstrcpy(info3.environment,driver->environment);
1549 fstrcpy(info3.driverpath,driver->driverpath);
1550 fstrcpy(info3.datafile,driver->datafile);
1551 fstrcpy(info3.configfile,driver->configfile);
1552 fstrcpy(info3.helpfile,driver->helpfile);
1553 fstrcpy(info3.monitorname,driver->monitorname);
1554 fstrcpy(info3.defaultdatatype,driver->defaultdatatype);
1555 info3.dependentfiles = driver->dependentfiles;
1557 return add_a_printer_driver_3(&info3);
1561 /****************************************************************************
1562 ****************************************************************************/
1563 static WERROR get_a_printer_driver_3_default(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, fstring in_prt, fstring in_arch)
1565 NT_PRINTER_DRIVER_INFO_LEVEL_3 info;
1569 fstrcpy(info.name, in_prt);
1570 fstrcpy(info.defaultdatatype, "RAW");
1572 fstrcpy(info.driverpath, "");
1573 fstrcpy(info.datafile, "");
1574 fstrcpy(info.configfile, "");
1575 fstrcpy(info.helpfile, "");
1577 if ((info.dependentfiles=(fstring *)malloc(2*sizeof(fstring))) == NULL)
1580 memset(info.dependentfiles, '\0', 2*sizeof(fstring));
1581 fstrcpy(info.dependentfiles[0], "");
1583 *info_ptr = memdup(&info, sizeof(info));
1588 /****************************************************************************
1589 ****************************************************************************/
1590 static WERROR get_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, fstring in_prt, fstring in_arch, uint32 version)
1592 NT_PRINTER_DRIVER_INFO_LEVEL_3 driver;
1593 TDB_DATA kbuf, dbuf;
1594 fstring architecture;
1599 ZERO_STRUCT(driver);
1601 get_short_archi(architecture, in_arch);
1603 DEBUG(8,("get_a_printer_driver_3: [%s%s/%d/%s]\n", DRIVERS_PREFIX, architecture, version, in_prt));
1605 slprintf(key, sizeof(key)-1, "%s%s/%d/%s", DRIVERS_PREFIX, architecture, version, in_prt);
1608 kbuf.dsize = strlen(key)+1;
1610 dbuf = tdb_fetch(tdb_drivers, kbuf);
1612 if (!dbuf.dptr) return get_a_printer_driver_3_default(info_ptr, in_prt, in_arch);
1614 if (!dbuf.dptr) return WERR_ACCESS_DENIED;
1616 len += tdb_unpack(dbuf.dptr, dbuf.dsize, "dffffffff",
1625 driver.defaultdatatype);
1628 while (len < dbuf.dsize) {
1631 tddfs = (fstring *)Realloc(driver.dependentfiles,
1632 sizeof(fstring)*(i+2));
1633 if (tddfs == NULL) {
1634 DEBUG(0,("get_a_printer_driver_3: failed to enlarge buffer!\n"));
1637 else driver.dependentfiles = tddfs;
1639 len += tdb_unpack(dbuf.dptr+len, dbuf.dsize-len, "f",
1640 &driver.dependentfiles[i]);
1643 if (driver.dependentfiles != NULL)
1644 fstrcpy(driver.dependentfiles[i], "");
1646 SAFE_FREE(dbuf.dptr);
1648 if (len != dbuf.dsize) {
1649 SAFE_FREE(driver.dependentfiles);
1651 return get_a_printer_driver_3_default(info_ptr, in_prt, in_arch);
1654 *info_ptr = (NT_PRINTER_DRIVER_INFO_LEVEL_3 *)memdup(&driver, sizeof(driver));
1659 /****************************************************************************
1660 ****************************************************************************/
1661 uint32 get_a_printer_driver_9x_compatible(pstring line, fstring model)
1663 NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3;
1669 slprintf(key, sizeof(key)-1, "%s%s/%d/%s", DRIVERS_PREFIX, "WIN40", 0, model);
1670 DEBUG(10,("driver key: [%s]\n", key));
1673 kbuf.dsize = strlen(key)+1;
1674 if (!tdb_exists(tdb_drivers, kbuf)) return False;
1677 get_a_printer_driver_3(&info3, model, "Windows 4.0", 0);
1679 DEBUGADD(10,("info3->name [%s]\n", info3->name));
1680 DEBUGADD(10,("info3->datafile [%s]\n", info3->datafile));
1681 DEBUGADD(10,("info3->helpfile [%s]\n", info3->helpfile));
1682 DEBUGADD(10,("info3->monitorname [%s]\n", info3->monitorname));
1683 DEBUGADD(10,("info3->defaultdatatype [%s]\n", info3->defaultdatatype));
1684 for (i=0; info3->dependentfiles && *info3->dependentfiles[i]; i++) {
1685 DEBUGADD(10,("info3->dependentfiles [%s]\n", info3->dependentfiles[i]));
1687 DEBUGADD(10,("info3->environment [%s]\n", info3->environment));
1688 DEBUGADD(10,("info3->driverpath [%s]\n", info3->driverpath));
1689 DEBUGADD(10,("info3->configfile [%s]\n", info3->configfile));
1691 /*pstrcat(line, info3->name); pstrcat(line, ":");*/
1692 trim_string(info3->configfile, "\\print$\\WIN40\\0\\", 0);
1693 pstrcat(line, info3->configfile);
1695 trim_string(info3->datafile, "\\print$\\WIN40\\0\\", 0);
1696 pstrcat(line, info3->datafile);
1698 trim_string(info3->helpfile, "\\print$\\WIN40\\0\\", 0);
1699 pstrcat(line, info3->helpfile);
1701 trim_string(info3->monitorname, "\\print$\\WIN40\\0\\", 0);
1702 pstrcat(line, info3->monitorname);
1704 pstrcat(line, "RAW"); /*info3->defaultdatatype);*/
1707 for (i=0; info3->dependentfiles &&
1708 *info3->dependentfiles[i]; i++) {
1709 if (i) pstrcat(line, ","); /* don't end in a "," */
1710 trim_string(info3->dependentfiles[i], "\\print$\\WIN40\\0\\", 0);
1711 pstrcat(line, info3->dependentfiles[i]);
1719 /****************************************************************************
1720 debugging function, dump at level 6 the struct in the logs
1721 ****************************************************************************/
1722 static uint32 dump_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
1725 NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3;
1728 DEBUG(106,("Dumping printer driver at level [%d]\n", level));
1734 if (driver.info_3 == NULL)
1737 info3=driver.info_3;
1739 DEBUGADD(106,("version:[%d]\n", info3->cversion));
1740 DEBUGADD(106,("name:[%s]\n", info3->name));
1741 DEBUGADD(106,("environment:[%s]\n", info3->environment));
1742 DEBUGADD(106,("driverpath:[%s]\n", info3->driverpath));
1743 DEBUGADD(106,("datafile:[%s]\n", info3->datafile));
1744 DEBUGADD(106,("configfile:[%s]\n", info3->configfile));
1745 DEBUGADD(106,("helpfile:[%s]\n", info3->helpfile));
1746 DEBUGADD(106,("monitorname:[%s]\n", info3->monitorname));
1747 DEBUGADD(106,("defaultdatatype:[%s]\n", info3->defaultdatatype));
1749 for (i=0; info3->dependentfiles &&
1750 *info3->dependentfiles[i]; i++) {
1751 DEBUGADD(106,("dependentfile:[%s]\n",
1752 info3->dependentfiles[i]));
1759 DEBUGADD(1,("Level not implemented\n"));
1767 /****************************************************************************
1768 ****************************************************************************/
1769 static int pack_devicemode(NT_DEVICEMODE *nt_devmode, char *buf, int buflen)
1773 len += tdb_pack(buf+len, buflen-len, "p", nt_devmode);
1775 if (!nt_devmode) return len;
1777 len += tdb_pack(buf+len, buflen-len, "ffwwwwwwwwwwwwwwwwwwddddddddddddddp",
1778 nt_devmode->devicename,
1779 nt_devmode->formname,
1781 nt_devmode->specversion,
1782 nt_devmode->driverversion,
1784 nt_devmode->driverextra,
1785 nt_devmode->orientation,
1786 nt_devmode->papersize,
1787 nt_devmode->paperlength,
1788 nt_devmode->paperwidth,
1791 nt_devmode->defaultsource,
1792 nt_devmode->printquality,
1795 nt_devmode->yresolution,
1796 nt_devmode->ttoption,
1797 nt_devmode->collate,
1798 nt_devmode->logpixels,
1801 nt_devmode->bitsperpel,
1802 nt_devmode->pelswidth,
1803 nt_devmode->pelsheight,
1804 nt_devmode->displayflags,
1805 nt_devmode->displayfrequency,
1806 nt_devmode->icmmethod,
1807 nt_devmode->icmintent,
1808 nt_devmode->mediatype,
1809 nt_devmode->dithertype,
1810 nt_devmode->reserved1,
1811 nt_devmode->reserved2,
1812 nt_devmode->panningwidth,
1813 nt_devmode->panningheight,
1814 nt_devmode->private);
1817 if (nt_devmode->private) {
1818 len += tdb_pack(buf+len, buflen-len, "B",
1819 nt_devmode->driverextra,
1820 nt_devmode->private);
1823 DEBUG(8,("Packed devicemode [%s]\n", nt_devmode->formname));
1828 /****************************************************************************
1829 ****************************************************************************/
1830 static int pack_specifics(NT_PRINTER_PARAM *param, char *buf, int buflen)
1834 while (param != NULL) {
1835 len += tdb_pack(buf+len, buflen-len, "pfdB",
1844 len += tdb_pack(buf+len, buflen-len, "p", param);
1850 /****************************************************************************
1851 delete a printer - this just deletes the printer info file, any open
1852 handles are not affected
1853 ****************************************************************************/
1854 uint32 del_a_printer(char *sharename)
1859 slprintf(key, sizeof(key)-1, "%s%s", PRINTERS_PREFIX, sharename);
1862 kbuf.dsize=strlen(key)+1;
1864 tdb_delete(tdb_printers, kbuf);
1868 /* FIXME!!! Reorder so this forward declaration is not necessary --jerry */
1869 static WERROR get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **, fstring);
1870 static void free_nt_printer_info_level_2(NT_PRINTER_INFO_LEVEL_2 **);
1871 /****************************************************************************
1872 ****************************************************************************/
1873 static WERROR update_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info)
1879 TDB_DATA kbuf, dbuf;
1882 * in addprinter: no servername and the printer is the name
1883 * in setprinter: servername is \\server
1884 * and printer is \\server\\printer
1886 * Samba manages only local printers.
1887 * we currently don't support things like path=\\other_server\printer
1890 if (info->servername[0]!='\0') {
1891 trim_string(info->printername, info->servername, NULL);
1892 trim_string(info->printername, "\\", NULL);
1893 info->servername[0]='\0';
1897 * JFM: one day I'll forget.
1898 * below that's info->portname because that's the SAMBA sharename
1899 * and I made NT 'thinks' it's the portname
1900 * the info->sharename is the thing you can name when you add a printer
1901 * that's the short-name when you create shared printer for 95/98
1902 * So I've made a limitation in SAMBA: you can only have 1 printer model
1903 * behind a SAMBA share.
1911 len += tdb_pack(buf+len, buflen-len, "dddddddddddfffffPfffff",
1914 info->default_priority,
1931 info->printprocessor,
1935 len += pack_devicemode(info->devmode, buf+len, buflen-len);
1937 len += pack_specifics(info->specific, buf+len, buflen-len);
1939 if (buflen != len) {
1942 tb = (char *)Realloc(buf, len);
1944 DEBUG(0,("update_a_printer_2: failed to enlarge buffer!\n"));
1954 slprintf(key, sizeof(key)-1, "%s%s", PRINTERS_PREFIX, info->sharename);
1957 kbuf.dsize = strlen(key)+1;
1961 ret = (tdb_store(tdb_printers, kbuf, dbuf, TDB_REPLACE) == 0? WERR_OK : WERR_NOMEM);
1964 if (!W_ERROR_IS_OK(ret))
1965 DEBUG(8, ("error updating printer to tdb on disk\n"));
1969 DEBUG(8,("packed printer [%s] with driver [%s] portname=[%s] len=%d\n",
1970 info->sharename, info->drivername, info->portname, len));
1976 /****************************************************************************
1977 ****************************************************************************/
1978 void add_a_specific_param(NT_PRINTER_INFO_LEVEL_2 *info_2, NT_PRINTER_PARAM **param)
1980 NT_PRINTER_PARAM *current;
1982 DEBUG(108,("add_a_specific_param\n"));
1984 (*param)->next=NULL;
1986 if (info_2->specific == NULL)
1988 info_2->specific=*param;
1992 current=info_2->specific;
1993 while (current->next != NULL) {
1994 current=current->next;
1996 current->next=*param;
2002 /****************************************************************************
2003 ****************************************************************************/
2004 BOOL unlink_specific_param_if_exist(NT_PRINTER_INFO_LEVEL_2 *info_2, NT_PRINTER_PARAM *param)
2006 NT_PRINTER_PARAM *current;
2007 NT_PRINTER_PARAM *previous;
2009 current=info_2->specific;
2012 if (current==NULL) return (False);
2014 if ( !strcmp(current->value, param->value) &&
2015 (strlen(current->value)==strlen(param->value)) ) {
2016 DEBUG(109,("deleting first value\n"));
2017 info_2->specific=current->next;
2018 SAFE_FREE(current->data);
2020 DEBUG(109,("deleted first value\n"));
2024 current=previous->next;
2026 while ( current!=NULL ) {
2027 if (!strcmp(current->value, param->value) &&
2028 strlen(current->value)==strlen(param->value) ) {
2029 DEBUG(109,("deleting current value\n"));
2030 previous->next=current->next;
2031 SAFE_FREE(current->data);
2033 DEBUG(109,("deleted current value\n"));
2037 previous=previous->next;
2038 current=current->next;
2043 /****************************************************************************
2044 Clean up and deallocate a (maybe partially) allocated NT_PRINTER_PARAM.
2045 ****************************************************************************/
2046 void free_nt_printer_param(NT_PRINTER_PARAM **param_ptr)
2048 NT_PRINTER_PARAM *param = *param_ptr;
2053 DEBUG(106,("free_nt_printer_param: deleting param [%s]\n", param->value));
2055 SAFE_FREE(param->data);
2056 SAFE_FREE(*param_ptr);
2059 /****************************************************************************
2060 Malloc and return an NT devicemode.
2061 ****************************************************************************/
2063 NT_DEVICEMODE *construct_nt_devicemode(const fstring default_devicename)
2066 * should I init this ones ???
2067 nt_devmode->devicename
2071 NT_DEVICEMODE *nt_devmode = (NT_DEVICEMODE *)malloc(sizeof(NT_DEVICEMODE));
2073 if (nt_devmode == NULL) {
2074 DEBUG(0,("construct_nt_devicemode: malloc fail.\n"));
2078 ZERO_STRUCTP(nt_devmode);
2080 safe_strcpy(adevice, default_devicename, sizeof(adevice));
2081 fstrcpy(nt_devmode->devicename, adevice);
2083 fstrcpy(nt_devmode->formname, "Letter");
2085 nt_devmode->specversion = 0x0401;
2086 nt_devmode->driverversion = 0x0400;
2087 nt_devmode->size = 0x00DC;
2088 nt_devmode->driverextra = 0x0000;
2089 nt_devmode->fields = FORMNAME | TTOPTION | PRINTQUALITY |
2090 DEFAULTSOURCE | COPIES | SCALE |
2091 PAPERSIZE | ORIENTATION;
2092 nt_devmode->orientation = 1;
2093 nt_devmode->papersize = PAPER_LETTER;
2094 nt_devmode->paperlength = 0;
2095 nt_devmode->paperwidth = 0;
2096 nt_devmode->scale = 0x64;
2097 nt_devmode->copies = 1;
2098 nt_devmode->defaultsource = BIN_FORMSOURCE;
2099 nt_devmode->printquality = RES_HIGH; /* 0x0258 */
2100 nt_devmode->color = COLOR_MONOCHROME;
2101 nt_devmode->duplex = DUP_SIMPLEX;
2102 nt_devmode->yresolution = 0;
2103 nt_devmode->ttoption = TT_SUBDEV;
2104 nt_devmode->collate = COLLATE_FALSE;
2105 nt_devmode->icmmethod = 0;
2106 nt_devmode->icmintent = 0;
2107 nt_devmode->mediatype = 0;
2108 nt_devmode->dithertype = 0;
2110 /* non utilisés par un driver d'imprimante */
2111 nt_devmode->logpixels = 0;
2112 nt_devmode->bitsperpel = 0;
2113 nt_devmode->pelswidth = 0;
2114 nt_devmode->pelsheight = 0;
2115 nt_devmode->displayflags = 0;
2116 nt_devmode->displayfrequency = 0;
2117 nt_devmode->reserved1 = 0;
2118 nt_devmode->reserved2 = 0;
2119 nt_devmode->panningwidth = 0;
2120 nt_devmode->panningheight = 0;
2122 nt_devmode->private = NULL;
2126 /****************************************************************************
2127 Deepcopy an NT devicemode.
2128 ****************************************************************************/
2130 NT_DEVICEMODE *dup_nt_devicemode(NT_DEVICEMODE *nt_devicemode)
2132 NT_DEVICEMODE *new_nt_devicemode = NULL;
2134 if ((new_nt_devicemode = (NT_DEVICEMODE *)memdup(nt_devicemode, sizeof(NT_DEVICEMODE))) == NULL) {
2135 DEBUG(0,("dup_nt_devicemode: malloc fail.\n"));
2139 new_nt_devicemode->private = NULL;
2140 if (nt_devicemode->private != NULL) {
2141 if ((new_nt_devicemode->private = memdup(nt_devicemode->private, nt_devicemode->driverextra)) == NULL) {
2142 SAFE_FREE(new_nt_devicemode);
2143 DEBUG(0,("dup_nt_devicemode: malloc fail.\n"));
2148 return new_nt_devicemode;
2151 /****************************************************************************
2152 Clean up and deallocate a (maybe partially) allocated NT_DEVICEMODE.
2153 ****************************************************************************/
2155 void free_nt_devicemode(NT_DEVICEMODE **devmode_ptr)
2157 NT_DEVICEMODE *nt_devmode = *devmode_ptr;
2159 if(nt_devmode == NULL)
2162 DEBUG(106,("free_nt_devicemode: deleting DEVMODE\n"));
2164 SAFE_FREE(nt_devmode->private);
2165 SAFE_FREE(*devmode_ptr);
2168 /****************************************************************************
2169 Clean up and deallocate a (maybe partially) allocated NT_PRINTER_INFO_LEVEL_2.
2170 ****************************************************************************/
2171 static void free_nt_printer_info_level_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr)
2173 NT_PRINTER_INFO_LEVEL_2 *info = *info_ptr;
2174 NT_PRINTER_PARAM *param_ptr;
2179 DEBUG(106,("free_nt_printer_info_level_2: deleting info\n"));
2181 free_nt_devicemode(&info->devmode);
2183 for(param_ptr = info->specific; param_ptr; ) {
2184 NT_PRINTER_PARAM *tofree = param_ptr;
2186 param_ptr = param_ptr->next;
2187 free_nt_printer_param(&tofree);
2190 SAFE_FREE(*info_ptr);
2194 /****************************************************************************
2195 ****************************************************************************/
2196 static int unpack_devicemode(NT_DEVICEMODE **nt_devmode, char *buf, int buflen)
2200 NT_DEVICEMODE devmode;
2202 ZERO_STRUCT(devmode);
2204 len += tdb_unpack(buf+len, buflen-len, "p", nt_devmode);
2206 if (!*nt_devmode) return len;
2208 len += tdb_unpack(buf+len, buflen-len, "ffwwwwwwwwwwwwwwwwwwddddddddddddddp",
2212 &devmode.specversion,
2213 &devmode.driverversion,
2215 &devmode.driverextra,
2216 &devmode.orientation,
2218 &devmode.paperlength,
2219 &devmode.paperwidth,
2222 &devmode.defaultsource,
2223 &devmode.printquality,
2226 &devmode.yresolution,
2232 &devmode.bitsperpel,
2234 &devmode.pelsheight,
2235 &devmode.displayflags,
2236 &devmode.displayfrequency,
2240 &devmode.dithertype,
2243 &devmode.panningwidth,
2244 &devmode.panningheight,
2247 if (devmode.private) {
2248 /* the len in tdb_unpack is an int value and
2249 * devmode.driverextra is only a short
2251 len += tdb_unpack(buf+len, buflen-len, "B", &extra_len, &devmode.private);
2252 devmode.driverextra=(uint16)extra_len;
2254 /* check to catch an invalid TDB entry so we don't segfault */
2255 if (devmode.driverextra == 0) {
2256 devmode.private = NULL;
2260 *nt_devmode = (NT_DEVICEMODE *)memdup(&devmode, sizeof(devmode));
2262 DEBUG(8,("Unpacked devicemode [%s](%s)\n", devmode.devicename, devmode.formname));
2263 if (devmode.private)
2264 DEBUG(8,("with a private section of %d bytes\n", devmode.driverextra));
2269 /****************************************************************************
2270 ****************************************************************************/
2271 static int unpack_specifics(NT_PRINTER_PARAM **list, char *buf, int buflen)
2274 NT_PRINTER_PARAM param, *p;
2279 len += tdb_unpack(buf+len, buflen-len, "p", &p);
2282 len += tdb_unpack(buf+len, buflen-len, "fdB",
2288 *list = memdup(¶m, sizeof(param));
2290 DEBUG(8,("specific: [%s], len: %d\n", param.value, param.data_len));
2296 static void map_to_os2_driver(fstring drivername)
2298 static BOOL initialised=False;
2299 static fstring last_from,last_to;
2300 char *mapfile = lp_os2_driver_map();
2301 char **lines = NULL;
2305 if (!strlen(drivername))
2312 *last_from = *last_to = 0;
2316 if (strequal(drivername,last_from)) {
2317 DEBUG(3,("Mapped Windows driver %s to OS/2 driver %s\n",drivername,last_to));
2318 fstrcpy(drivername,last_to);
2322 lines = file_lines_load(mapfile, &numlines);
2323 if (numlines == 0) {
2324 DEBUG(0,("No entries in OS/2 driver map %s\n",mapfile));
2328 DEBUG(4,("Scanning OS/2 driver map %s\n",mapfile));
2330 for( i = 0; i < numlines; i++) {
2331 char *nt_name = lines[i];
2332 char *os2_name = strchr(nt_name,'=');
2339 while (isspace(*nt_name))
2342 if (!*nt_name || strchr("#;",*nt_name))
2346 int l = strlen(nt_name);
2347 while (l && isspace(nt_name[l-1])) {
2353 while (isspace(*os2_name))
2357 int l = strlen(os2_name);
2358 while (l && isspace(os2_name[l-1])) {
2364 if (strequal(nt_name,drivername)) {
2365 DEBUG(3,("Mapped windows driver %s to os2 driver%s\n",drivername,os2_name));
2366 fstrcpy(last_from,drivername);
2367 fstrcpy(last_to,os2_name);
2368 fstrcpy(drivername,os2_name);
2369 file_lines_free(lines);
2374 file_lines_free(lines);
2377 /****************************************************************************
2378 get a default printer info 2 struct
2379 ****************************************************************************/
2380 static WERROR get_a_printer_2_default(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstring sharename)
2383 NT_PRINTER_INFO_LEVEL_2 info;
2387 snum = lp_servicenumber(sharename);
2389 slprintf(info.servername, sizeof(info.servername)-1, "\\\\%s", get_called_name());
2390 slprintf(info.printername, sizeof(info.printername)-1, "\\\\%s\\%s",
2391 get_called_name(), sharename);
2392 fstrcpy(info.sharename, sharename);
2393 fstrcpy(info.portname, SAMBA_PRINTER_PORT_NAME);
2394 fstrcpy(info.drivername, lp_printerdriver(snum));
2396 /* by setting the driver name to an empty string, a local NT admin
2397 can now run the **local** APW to install a local printer driver
2398 for a Samba shared printer in 2.2. Without this, drivers **must** be
2399 installed on the Samba server for NT clients --jerry */
2400 #if 0 /* JERRY --do not uncomment-- */
2401 if (!*info.drivername)
2402 fstrcpy(info.drivername, "NO DRIVER AVAILABLE FOR THIS PRINTER");
2406 DEBUG(10,("get_a_printer_2_default: driver name set to [%s]\n", info.drivername));
2408 pstrcpy(info.comment, "");
2409 fstrcpy(info.printprocessor, "winprint");
2410 fstrcpy(info.datatype, "RAW");
2412 info.attributes = PRINTER_ATTRIBUTE_SHARED \
2413 | PRINTER_ATTRIBUTE_LOCAL \
2414 | PRINTER_ATTRIBUTE_RAW_ONLY \
2415 | PRINTER_ATTRIBUTE_QUEUED ; /* attributes */
2417 info.starttime = 0; /* Minutes since 12:00am GMT */
2418 info.untiltime = 0; /* Minutes since 12:00am GMT */
2420 info.default_priority = 1;
2421 info.setuptime = (uint32)time(NULL) - 86400; /* minus 1 day */
2424 * I changed this as I think it is better to have a generic
2425 * DEVMODE than to crash Win2k explorer.exe --jerry
2426 * See the HP Deskjet 990c Win2k drivers for an example.
2429 #if 0 /* JRA - NO NOT CHANGE ! */
2430 info.devmode = NULL;
2433 * We should not return a default devicemode, as this causes
2434 * Win2K to not send the correct one on PCL drivers. It needs to
2435 * see a null devicemode so it can then overwrite the devicemode
2436 * on OpenPrinterEx. Yes this *is* insane :-). JRA.
2438 if ((info.devmode = construct_nt_devicemode(info.printername)) == NULL)
2442 /* This will get the current RPC talloc context, but we should be
2443 passing this as a parameter... fixme... JRA ! */
2445 if (!nt_printing_getsec(get_talloc_ctx(), sharename, &info.secdesc_buf))
2448 *info_ptr = (NT_PRINTER_INFO_LEVEL_2 *)memdup(&info, sizeof(info));
2450 DEBUG(0,("get_a_printer_2_default: malloc fail.\n"));
2459 free_nt_devicemode(&info.devmode);
2460 return WERR_ACCESS_DENIED;
2463 /****************************************************************************
2464 ****************************************************************************/
2465 static WERROR get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstring sharename)
2468 NT_PRINTER_INFO_LEVEL_2 info;
2470 TDB_DATA kbuf, dbuf;
2471 fstring printername;
2475 slprintf(key, sizeof(key)-1, "%s%s", PRINTERS_PREFIX, sharename);
2478 kbuf.dsize = strlen(key)+1;
2480 dbuf = tdb_fetch(tdb_printers, kbuf);
2482 return get_a_printer_2_default(info_ptr, sharename);
2484 len += tdb_unpack(dbuf.dptr+len, dbuf.dsize-len, "dddddddddddfffffPfffff",
2487 &info.default_priority,
2504 info.printprocessor,
2508 /* Samba has to have shared raw drivers. */
2509 info.attributes |= (PRINTER_ATTRIBUTE_SHARED|PRINTER_ATTRIBUTE_RAW_ONLY);
2511 /* Restore the stripped strings. */
2512 slprintf(info.servername, sizeof(info.servername)-1, "\\\\%s", get_called_name());
2513 slprintf(printername, sizeof(printername)-1, "\\\\%s\\%s", get_called_name(),
2515 fstrcpy(info.printername, printername);
2517 len += unpack_devicemode(&info.devmode,dbuf.dptr+len, dbuf.dsize-len);
2520 * Some client drivers freak out if there is a NULL devmode
2521 * (probably the driver is not checking before accessing
2522 * the devmode pointer) --jerry
2526 DEBUG(8,("get_a_printer_2: Constructing a default device mode for [%s]\n",
2528 info.devmode = construct_nt_devicemode(printername);
2531 len += unpack_specifics(&info.specific,dbuf.dptr+len, dbuf.dsize-len);
2533 /* This will get the current RPC talloc context, but we should be
2534 passing this as a parameter... fixme... JRA ! */
2536 nt_printing_getsec(get_talloc_ctx(), sharename, &info.secdesc_buf);
2538 /* Fix for OS/2 drivers. */
2540 if (get_remote_arch() == RA_OS2)
2541 map_to_os2_driver(info.drivername);
2543 SAFE_FREE(dbuf.dptr);
2544 *info_ptr=memdup(&info, sizeof(info));
2546 DEBUG(9,("Unpacked printer [%s] name [%s] running driver [%s]\n",
2547 sharename, info.printername, info.drivername));
2552 /****************************************************************************
2553 debugging function, dump at level 6 the struct in the logs
2554 ****************************************************************************/
2555 static uint32 dump_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
2558 NT_PRINTER_INFO_LEVEL_2 *info2;
2560 DEBUG(106,("Dumping printer at level [%d]\n", level));
2566 if (printer.info_2 == NULL)
2570 info2=printer.info_2;
2572 DEBUGADD(106,("attributes:[%d]\n", info2->attributes));
2573 DEBUGADD(106,("priority:[%d]\n", info2->priority));
2574 DEBUGADD(106,("default_priority:[%d]\n", info2->default_priority));
2575 DEBUGADD(106,("starttime:[%d]\n", info2->starttime));
2576 DEBUGADD(106,("untiltime:[%d]\n", info2->untiltime));
2577 DEBUGADD(106,("status:[%d]\n", info2->status));
2578 DEBUGADD(106,("cjobs:[%d]\n", info2->cjobs));
2579 DEBUGADD(106,("averageppm:[%d]\n", info2->averageppm));
2580 DEBUGADD(106,("changeid:[%d]\n", info2->changeid));
2581 DEBUGADD(106,("c_setprinter:[%d]\n", info2->c_setprinter));
2582 DEBUGADD(106,("setuptime:[%d]\n", info2->setuptime));
2584 DEBUGADD(106,("servername:[%s]\n", info2->servername));
2585 DEBUGADD(106,("printername:[%s]\n", info2->printername));
2586 DEBUGADD(106,("sharename:[%s]\n", info2->sharename));
2587 DEBUGADD(106,("portname:[%s]\n", info2->portname));
2588 DEBUGADD(106,("drivername:[%s]\n", info2->drivername));
2589 DEBUGADD(106,("comment:[%s]\n", info2->comment));
2590 DEBUGADD(106,("location:[%s]\n", info2->location));
2591 DEBUGADD(106,("sepfile:[%s]\n", info2->sepfile));
2592 DEBUGADD(106,("printprocessor:[%s]\n", info2->printprocessor));
2593 DEBUGADD(106,("datatype:[%s]\n", info2->datatype));
2594 DEBUGADD(106,("parameters:[%s]\n", info2->parameters));
2600 DEBUGADD(1,("Level not implemented\n"));
2608 /****************************************************************************
2609 Get the parameters we can substitute in an NT print job.
2610 ****************************************************************************/
2612 void get_printer_subst_params(int snum, fstring *printername, fstring *sharename, fstring *portname)
2614 NT_PRINTER_INFO_LEVEL *printer = NULL;
2616 **printername = **sharename = **portname = '\0';
2618 if (!W_ERROR_IS_OK(get_a_printer(&printer, 2, lp_servicename(snum))))
2621 fstrcpy(*printername, printer->info_2->printername);
2622 fstrcpy(*sharename, printer->info_2->sharename);
2623 fstrcpy(*portname, printer->info_2->portname);
2625 free_a_printer(&printer, 2);
2629 * The function below are the high level ones.
2630 * only those ones must be called from the spoolss code.
2634 /****************************************************************************
2635 Modify a printer. This is called from SETPRINTERDATA/DELETEPRINTERDATA.
2636 ****************************************************************************/
2638 WERROR mod_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
2642 dump_a_printer(printer, level);
2649 * Update the changestamp. Emperical tests show that the
2650 * ChangeID is always updated,but c_setprinter is only
2651 * incremented on a SetPrinter() call.
2654 time_t time_unix = time(NULL);
2656 /* ChangeID **must** be increasing over the lifetime
2657 of client's spoolss service in order for the
2658 client's cache to show updates */
2660 printer.info_2->changeid = time_unix * 100;
2663 * Because one day someone will ask:
2664 * NT->NT An admin connection to a remote
2665 * printer show changes imeediately in
2666 * the properities dialog
2668 * A non-admin connection will only show the
2669 * changes after viewing the properites page
2670 * 2 times. Seems to be related to a
2671 * race condition in the client between the spooler
2672 * updating the local cache and the Explorer.exe GUI
2673 * actually displaying the properties.
2675 * This is fixed in Win2k. admin/non-admin
2676 * connections both display changes immediately.
2681 result=update_a_printer_2(printer.info_2);
2685 result=WERR_UNKNOWN_LEVEL;
2692 /****************************************************************************
2693 Add a printer. This is called from ADDPRINTER(EX) and also SETPRINTER.
2694 We split this out from mod_a_printer as it updates the id's and timestamps.
2695 ****************************************************************************/
2697 WERROR add_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
2701 dump_a_printer(printer, level);
2708 * Update the changestamp. See comments in mod_a_printer()
2712 time_t time_unix = time(NULL);
2714 printer.info_2->changeid = time_unix * 100;
2715 printer.info_2->c_setprinter++;
2717 result=update_a_printer_2(printer.info_2);
2721 result=WERR_UNKNOWN_LEVEL;
2728 /****************************************************************************
2729 Initialize printer devmode & data with previously saved driver init values.
2730 ****************************************************************************/
2731 static uint32 set_driver_init_2(NT_PRINTER_INFO_LEVEL_2 *info_ptr)
2735 TDB_DATA kbuf, dbuf;
2736 NT_PRINTER_PARAM *current;
2737 NT_PRINTER_INFO_LEVEL_2 info;
2741 slprintf(key, sizeof(key)-1, "%s%s", DRIVER_INIT_PREFIX, info_ptr->drivername);
2744 kbuf.dsize = strlen(key)+1;
2746 dbuf = tdb_fetch(tdb_drivers, kbuf);
2751 * Get the saved DEVMODE..
2753 len += unpack_devicemode(&info.devmode,dbuf.dptr+len, dbuf.dsize-len);
2756 * The saved DEVMODE contains the devicename from the printer used during
2757 * the initialization save. Change it to reflect the new printer.
2759 ZERO_STRUCT(info.devmode->devicename);
2760 fstrcpy(info.devmode->devicename, info_ptr->printername);
2763 * Bind the saved DEVMODE to the new the printer.
2765 free_nt_devicemode(&info_ptr->devmode);
2766 info_ptr->devmode = info.devmode;
2768 DEBUG(10,("set_driver_init_2: Set printer [%s] init DEVMODE for driver [%s]\n",
2769 info_ptr->printername, info_ptr->drivername));
2772 * There should not be any printer data 'specifics' already set during the
2773 * add printer operation, if there are delete them.
2775 while ( (current=info_ptr->specific) != NULL ) {
2776 info_ptr->specific=current->next;
2777 SAFE_FREE(current->data);
2782 * Add the printer data 'specifics' to the new printer
2784 len += unpack_specifics(&info_ptr->specific,dbuf.dptr+len, dbuf.dsize-len);
2786 SAFE_FREE(dbuf.dptr);
2791 /****************************************************************************
2792 Initialize printer devmode & data with previously saved driver init values.
2793 When a printer is created using AddPrinter, the drivername bound to the
2794 printer is used to lookup previously saved driver initialization info, which
2795 is bound to the new printer.
2796 ****************************************************************************/
2798 uint32 set_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level)
2806 result=set_driver_init_2(printer->info_2);
2817 /****************************************************************************
2818 Pack up the DEVMODE and specifics for a printer into a 'driver init' entry
2819 in the tdb. Note: this is different from the driver entry and the printer
2820 entry. There should be a single driver init entry for each driver regardless
2821 of whether it was installed from NT or 2K. Technically, they should be
2822 different, but they work out to the same struct.
2823 ****************************************************************************/
2824 static uint32 update_driver_init_2(NT_PRINTER_INFO_LEVEL_2 *info)
2828 int buflen, len, ret;
2829 TDB_DATA kbuf, dbuf;
2836 len += pack_devicemode(info->devmode, buf+len, buflen-len);
2838 len += pack_specifics(info->specific, buf+len, buflen-len);
2840 if (buflen != len) {
2843 tb = (char *)Realloc(buf, len);
2845 DEBUG(0, ("update_driver_init_2: failed to enlarge buffer!\n"));
2854 slprintf(key, sizeof(key)-1, "%s%s", DRIVER_INIT_PREFIX, info->drivername);
2857 kbuf.dsize = strlen(key)+1;
2861 ret = tdb_store(tdb_drivers, kbuf, dbuf, TDB_REPLACE);
2865 DEBUG(8, ("update_driver_init_2: error updating printer init to tdb on disk\n"));
2869 DEBUG(10,("update_driver_init_2: Saved printer [%s] init DEVMODE & specifics for driver [%s]\n",
2870 info->sharename, info->drivername));
2875 /****************************************************************************
2876 Update (i.e. save) the driver init info (DEVMODE and specifics) for a printer
2877 ****************************************************************************/
2879 static uint32 update_driver_init(NT_PRINTER_INFO_LEVEL printer, uint32 level)
2883 dump_a_printer(printer, level);
2889 result=update_driver_init_2(printer.info_2);
2900 /****************************************************************************
2901 Convert the printer data value, a REG_BINARY array, into an initialization
2902 DEVMODE. Note: the array must be parsed as if it was a DEVMODE in an rpc...
2903 got to keep the endians happy :).
2904 ****************************************************************************/
2906 static BOOL convert_driver_init(NT_PRINTER_PARAM *param, TALLOC_CTX *ctx, NT_DEVICEMODE *nt_devmode)
2908 BOOL result = False;
2912 ZERO_STRUCT(devmode);
2914 prs_init(&ps, 0, ctx, UNMARSHALL);
2915 ps.data_p = (char *)param->data;
2916 ps.buffer_size = param->data_len;
2918 if (spoolss_io_devmode("phantom DEVMODE", &ps, 0, &devmode))
2919 result = convert_devicemode("", &devmode, &nt_devmode);
2921 DEBUG(10,("convert_driver_init: error parsing DEVMODE\n"));
2926 /****************************************************************************
2927 Set the DRIVER_INIT info in the tdb. Requires Win32 client code that:
2929 1. Use the driver's config DLL to this UNC printername and:
2930 a. Call DrvPrintEvent with PRINTER_EVENT_INITIALIZE
2931 b. Call DrvConvertDevMode with CDM_DRIVER_DEFAULT to get default DEVMODE
2932 2. Call SetPrinterData with the 'magic' key and the DEVMODE as data.
2934 The last step triggers saving the "driver initialization" information for
2935 this printer into the tdb. Later, new printers that use this driver will
2936 have this initialization information bound to them. This simulates the
2937 driver initialization, as if it had run on the Samba server (as it would
2940 The Win32 client side code requirement sucks! But until we can run arbitrary
2941 Win32 printer driver code on any Unix that Samba runs on, we are stuck with it.
2943 It would have been easier to use SetPrinter because all the UNMARSHALLING of
2944 the DEVMODE is done there, but 2K/XP clients do not set the DEVMODE... think
2945 about it and you will realize why. JRR 010720
2946 ****************************************************************************/
2948 static WERROR save_driver_init_2(NT_PRINTER_INFO_LEVEL *printer, NT_PRINTER_PARAM *param)
2950 WERROR status = WERR_OK;
2951 TALLOC_CTX *ctx = NULL;
2952 NT_DEVICEMODE *nt_devmode = NULL;
2953 NT_DEVICEMODE *tmp_devmode = printer->info_2->devmode;
2956 * Set devmode on printer info, so entire printer initialization can be
2959 if ((ctx = talloc_init()) == NULL)
2962 if ((nt_devmode = (NT_DEVICEMODE*)malloc(sizeof(NT_DEVICEMODE))) == NULL) {
2963 status = WERR_NOMEM;
2967 ZERO_STRUCTP(nt_devmode);
2970 * The DEVMODE is held in the 'data' component of the param in raw binary.
2971 * Convert it to to a devmode structure
2973 if (!convert_driver_init(param, ctx, nt_devmode)) {
2974 DEBUG(10,("save_driver_init_2: error converting DEVMODE\n"));
2975 status = WERR_INVALID_PARAM;
2980 * Pack up and add (or update) the DEVMODE and any current printer data to
2981 * a 'driver init' element in the tdb
2984 printer->info_2->devmode = nt_devmode;
2985 if (update_driver_init(*printer, 2)!=0) {
2986 DEBUG(10,("save_driver_init_2: error updating DEVMODE\n"));
2987 status = WERR_NOMEM;
2992 * If driver initialization info was successfully saved, set the current
2993 * printer to match it. This allows initialization of the current printer
2994 * as well as the driver.
2996 status = mod_a_printer(*printer, 2);
2997 if (!W_ERROR_IS_OK(status)) {
2998 DEBUG(10,("save_driver_init_2: error setting DEVMODE on printer [%s]\n",
2999 printer->info_2->printername));
3003 talloc_destroy(ctx);
3005 SAFE_FREE(nt_devmode->private);
3006 SAFE_FREE(nt_devmode);
3007 printer->info_2->devmode = tmp_devmode;
3012 /****************************************************************************
3013 Update the driver init info (DEVMODE and specifics) for a printer
3014 ****************************************************************************/
3016 WERROR save_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level, NT_PRINTER_PARAM *param)
3018 WERROR status = WERR_OK;
3024 status=save_driver_init_2(printer, param);
3028 status=WERR_UNKNOWN_LEVEL;
3035 /****************************************************************************
3036 Get a NT_PRINTER_INFO_LEVEL struct. It returns malloced memory.
3037 ****************************************************************************/
3039 WERROR get_a_printer(NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level, fstring sharename)
3042 NT_PRINTER_INFO_LEVEL *printer = NULL;
3046 DEBUG(10,("get_a_printer: [%s] level %u\n", sharename, (unsigned int)level));
3052 if ((printer = (NT_PRINTER_INFO_LEVEL *)malloc(sizeof(NT_PRINTER_INFO_LEVEL))) == NULL) {
3053 DEBUG(0,("get_a_printer: malloc fail.\n"));
3056 ZERO_STRUCTP(printer);
3057 result=get_a_printer_2(&printer->info_2, sharename);
3058 if (W_ERROR_IS_OK(result)) {
3059 dump_a_printer(*printer, level);
3060 *pp_printer = printer;
3067 result=WERR_UNKNOWN_LEVEL;
3071 DEBUG(10,("get_a_printer: [%s] level %u returning %s\n", sharename, (unsigned int)level, werror_str(result)));
3076 /****************************************************************************
3077 Deletes a NT_PRINTER_INFO_LEVEL struct.
3078 ****************************************************************************/
3080 uint32 free_a_printer(NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level)
3083 NT_PRINTER_INFO_LEVEL *printer = *pp_printer;
3085 DEBUG(104,("freeing a printer at level [%d]\n", level));
3087 if (printer == NULL)
3094 if (printer->info_2 != NULL)
3096 free_nt_printer_info_level_2(&printer->info_2);
3110 SAFE_FREE(*pp_printer);
3114 /****************************************************************************
3115 ****************************************************************************/
3116 uint32 add_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
3119 DEBUG(104,("adding a printer at level [%d]\n", level));
3120 dump_a_printer_driver(driver, level);
3126 result=add_a_printer_driver_3(driver.info_3);
3132 result=add_a_printer_driver_6(driver.info_6);
3142 /****************************************************************************
3143 ****************************************************************************/
3144 WERROR get_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL *driver, uint32 level,
3145 fstring printername, fstring architecture, uint32 version)
3153 result=get_a_printer_driver_3(&driver->info_3, printername, architecture, version);
3161 if (W_ERROR_IS_OK(result))
3162 dump_a_printer_driver(*driver, level);
3166 /****************************************************************************
3167 ****************************************************************************/
3168 uint32 free_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
3176 NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3;
3177 if (driver.info_3 != NULL)
3179 info3=driver.info_3;
3180 SAFE_FREE(info3->dependentfiles);
3181 ZERO_STRUCTP(info3);
3193 NT_PRINTER_DRIVER_INFO_LEVEL_6 *info6;
3194 if (driver.info_6 != NULL)
3196 info6=driver.info_6;
3197 SAFE_FREE(info6->dependentfiles);
3198 SAFE_FREE(info6->previousnames);
3199 ZERO_STRUCTP(info6);
3217 /****************************************************************************
3218 Determine whether or not a particular driver is currently assigned
3220 ****************************************************************************/
3221 BOOL printer_driver_in_use (char *arch, char *driver)
3223 TDB_DATA kbuf, newkey, dbuf;
3224 NT_PRINTER_INFO_LEVEL_2 info;
3228 if (!nt_printing_init())
3231 DEBUG(5,("printer_driver_in_use: Beginning search through printers.tdb...\n"));
3233 /* loop through the printers.tdb and check for the drivername */
3234 for (kbuf = tdb_firstkey(tdb_printers); kbuf.dptr;
3235 newkey = tdb_nextkey(tdb_printers, kbuf), safe_free(kbuf.dptr), kbuf=newkey)
3238 dbuf = tdb_fetch(tdb_printers, kbuf);
3242 if (strncmp(kbuf.dptr, PRINTERS_PREFIX, strlen(PRINTERS_PREFIX)) != 0)
3245 ret = tdb_unpack(dbuf.dptr, dbuf.dsize, "dddddddddddfffffPfffff",
3248 &info.default_priority,
3265 info.printprocessor,
3269 SAFE_FREE(dbuf.dptr);
3272 DEBUG (0,("printer_driver_in_use: tdb_unpack failed for printer %s\n",
3277 DEBUG (10,("printer_driver_in_use: Printer - %s (%s)\n",
3278 info.printername, info.drivername));
3280 if (strcmp(info.drivername, driver) == 0)
3282 DEBUG(5,("printer_driver_in_use: Printer %s using %s\n",
3283 info.printername, driver));
3287 DEBUG(5,("printer_driver_in_use: Completed search through printers.tdb...\n"));
3291 /* report that the driver is in use by default */
3295 /****************************************************************************
3296 Remove a printer driver from the TDB. This assumes that the the driver was
3297 previously looked up.
3298 ***************************************************************************/
3299 WERROR delete_printer_driver (NT_PRINTER_DRIVER_INFO_LEVEL_3 *i)
3306 get_short_archi(arch, i->environment);
3307 slprintf(key, sizeof(key)-1, "%s%s/%d/%s", DRIVERS_PREFIX,
3308 arch, i->cversion, i->name);
3309 DEBUG(5,("delete_printer_driver: key = [%s]\n", key));
3312 kbuf.dsize=strlen(key)+1;
3314 if (tdb_delete(tdb_drivers, kbuf) == -1) {
3315 DEBUG (0,("delete_printer_driver: fail to delete %s!\n", key));
3316 return WERR_ACCESS_DENIED;
3319 DEBUG(5,("delete_printer_driver: [%s] driver delete successful.\n",
3324 /****************************************************************************
3325 ****************************************************************************/
3326 BOOL get_specific_param_by_index(NT_PRINTER_INFO_LEVEL printer, uint32 level, uint32 param_index,
3327 fstring value, uint8 **data, uint32 *type, uint32 *len)
3329 /* right now that's enough ! */
3330 NT_PRINTER_PARAM *param;
3333 param=printer.info_2->specific;
3335 while (param != NULL && i < param_index) {
3343 /* exited because it exist */
3345 StrnCpy(value, param->value, sizeof(fstring)-1);
3346 *data=(uint8 *)malloc(param->data_len*sizeof(uint8));
3349 ZERO_STRUCTP(*data);
3350 memcpy(*data, param->data, param->data_len);
3351 *len=param->data_len;
3355 /****************************************************************************
3356 ****************************************************************************/
3357 BOOL get_specific_param(NT_PRINTER_INFO_LEVEL printer, uint32 level,
3358 fstring value, uint8 **data, uint32 *type, uint32 *len)
3360 /* right now that's enough ! */
3361 NT_PRINTER_PARAM *param;
3363 DEBUG(10, ("get_specific_param\n"));
3365 param=printer.info_2->specific;
3367 while (param != NULL)
3369 #if 1 /* JRA - I think this should be case insensitive.... */
3370 if ( strequal(value, param->value)
3372 if ( !strcmp(value, param->value)
3374 && strlen(value)==strlen(param->value))
3382 DEBUGADD(10, ("get_specific_param: found one param\n"));
3383 /* exited because it exist */
3386 *data=(uint8 *)malloc(param->data_len*sizeof(uint8));
3389 memcpy(*data, param->data, param->data_len);
3390 *len=param->data_len;
3392 DEBUGADD(10, ("get_specific_param: exit true\n"));
3395 DEBUGADD(10, ("get_specific_param: exit false\n"));
3399 /****************************************************************************
3400 Store a security desc for a printer.
3401 ****************************************************************************/
3403 WERROR nt_printing_setsec(char *printername, SEC_DESC_BUF *secdesc_ctr)
3405 SEC_DESC_BUF *new_secdesc_ctr = NULL;
3406 SEC_DESC_BUF *old_secdesc_ctr = NULL;
3408 TALLOC_CTX *mem_ctx = NULL;
3412 mem_ctx = talloc_init();
3413 if (mem_ctx == NULL)
3416 /* The old owner and group sids of the security descriptor are not
3417 present when new ACEs are added or removed by changing printer
3418 permissions through NT. If they are NULL in the new security
3419 descriptor then copy them over from the old one. */
3421 if (!secdesc_ctr->sec->owner_sid || !secdesc_ctr->sec->grp_sid) {
3422 DOM_SID *owner_sid, *group_sid;
3423 SEC_ACL *dacl, *sacl;
3424 SEC_DESC *psd = NULL;
3427 nt_printing_getsec(mem_ctx, printername, &old_secdesc_ctr);
3429 /* Pick out correct owner and group sids */
3431 owner_sid = secdesc_ctr->sec->owner_sid ?
3432 secdesc_ctr->sec->owner_sid :
3433 old_secdesc_ctr->sec->owner_sid;
3435 group_sid = secdesc_ctr->sec->grp_sid ?
3436 secdesc_ctr->sec->grp_sid :
3437 old_secdesc_ctr->sec->grp_sid;
3439 dacl = secdesc_ctr->sec->dacl ?
3440 secdesc_ctr->sec->dacl :
3441 old_secdesc_ctr->sec->dacl;
3443 sacl = secdesc_ctr->sec->sacl ?
3444 secdesc_ctr->sec->sacl :
3445 old_secdesc_ctr->sec->sacl;
3447 /* Make a deep copy of the security descriptor */
3449 psd = make_sec_desc(mem_ctx, secdesc_ctr->sec->revision,
3450 owner_sid, group_sid,
3455 new_secdesc_ctr = make_sec_desc_buf(mem_ctx, size, psd);
3458 if (!new_secdesc_ctr) {
3459 new_secdesc_ctr = secdesc_ctr;
3462 /* Store the security descriptor in a tdb */
3464 prs_init(&ps, (uint32)sec_desc_size(new_secdesc_ctr->sec) +
3465 sizeof(SEC_DESC_BUF), mem_ctx, MARSHALL);
3467 if (!sec_io_desc_buf("nt_printing_setsec", &new_secdesc_ctr,
3469 status = WERR_BADFUNC;
3473 slprintf(key, sizeof(key)-1, "SECDESC/%s", printername);
3475 if (tdb_prs_store(tdb_printers, key, &ps)==0) {
3478 DEBUG(1,("Failed to store secdesc for %s\n", printername));
3479 status = WERR_BADFUNC;
3482 /* Free malloc'ed memory */
3488 talloc_destroy(mem_ctx);
3492 /****************************************************************************
3493 Construct a default security descriptor buffer for a printer.
3494 ****************************************************************************/
3496 static SEC_DESC_BUF *construct_default_printer_sdb(TALLOC_CTX *ctx)
3500 SEC_ACL *psa = NULL;
3501 SEC_DESC_BUF *sdb = NULL;
3502 SEC_DESC *psd = NULL;
3505 enum SID_NAME_USE name_type;
3507 /* Create an ACE where Everyone is allowed to print */
3509 init_sec_access(&sa, PRINTER_ACE_PRINT);
3510 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
3511 sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
3513 /* Make the security descriptor owned by the Administrators group
3514 on the PDC of the domain. */
3516 if (winbind_lookup_name(lp_workgroup(), &owner_sid, &name_type)) {
3517 sid_append_rid(&owner_sid, DOMAIN_USER_RID_ADMIN);
3521 /* Backup plan - make printer owned by admins or root.
3522 This should emulate a lanman printer as security
3523 settings can't be changed. */
3525 sid_peek_rid(&owner_sid, &owner_rid);
3527 if (owner_rid != BUILTIN_ALIAS_RID_PRINT_OPS &&
3528 owner_rid != BUILTIN_ALIAS_RID_ADMINS &&
3529 owner_rid != DOMAIN_USER_RID_ADMIN &&
3530 !lookup_name("root", &owner_sid, &name_type)) {
3531 sid_copy(&owner_sid, &global_sid_World);
3535 init_sec_access(&sa, PRINTER_ACE_FULL_CONTROL);
3536 init_sec_ace(&ace[1], &owner_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
3537 sa, SEC_ACE_FLAG_OBJECT_INHERIT |
3538 SEC_ACE_FLAG_INHERIT_ONLY);
3540 init_sec_access(&sa, PRINTER_ACE_FULL_CONTROL);
3541 init_sec_ace(&ace[2], &owner_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
3542 sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
3544 /* The ACL revision number in rpc_secdesc.h differs from the one
3545 created by NT when setting ACE entries in printer
3546 descriptors. NT4 complains about the property being edited by a
3549 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) != NULL) {
3550 psd = make_sec_desc(ctx, SEC_DESC_REVISION,