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);
268 /* Cope with byte-reversed older versions of the db. */
269 vers_id = tdb_fetch_int32(tdb_drivers, vstring);
270 if ((vers_id != NTDRIVERS_DATABASE_VERSION) && (IREV(vers_id) == NTDRIVERS_DATABASE_VERSION)) {
271 /* Written on a bigendian machine with old fetch_int code. Save as le. */
272 tdb_store_int32(tdb_drivers, vstring, NTDRIVERS_DATABASE_VERSION);
273 vers_id = NTDRIVERS_DATABASE_VERSION;
276 if (vers_id != NTDRIVERS_DATABASE_VERSION) {
278 if ((vers_id == NTDRIVERS_DATABASE_VERSION_1) || (IREV(vers_id) == NTDRIVERS_DATABASE_VERSION_1)) {
279 if (!upgrade_to_version_2())
282 tdb_traverse(tdb_drivers, tdb_traverse_delete_fn, NULL);
284 tdb_store_int32(tdb_drivers, vstring, NTDRIVERS_DATABASE_VERSION);
287 tdb_unlock_bystring(tdb_drivers, vstring);
292 /****************************************************************************
293 get builtin form struct list
294 ****************************************************************************/
295 int get_builtin_ntforms(nt_forms_struct **list)
297 *list = (nt_forms_struct *)memdup(&default_forms[0], sizeof(default_forms));
298 return sizeof(default_forms) / sizeof(default_forms[0]);
301 /****************************************************************************
302 get a builtin form struct
303 ****************************************************************************/
305 BOOL get_a_builtin_ntform(UNISTR2 *uni_formname,nt_forms_struct *form)
309 unistr2_to_ascii(form_name, uni_formname, sizeof(form_name)-1);
310 DEBUGADD(6,("Looking for builtin form %s \n", form_name));
311 count = sizeof(default_forms) / sizeof(default_forms[0]);
312 for (i=0;i<count;i++) {
313 if (strequal(form_name,default_forms[i].name)) {
314 DEBUGADD(6,("Found builtin form %s \n", form_name));
315 memcpy(form,&default_forms[i],sizeof(*form));
323 /****************************************************************************
324 get a form struct list
325 ****************************************************************************/
326 int get_ntforms(nt_forms_struct **list)
328 TDB_DATA kbuf, newkey, dbuf;
330 nt_forms_struct form;
335 for (kbuf = tdb_firstkey(tdb_forms);
337 newkey = tdb_nextkey(tdb_forms, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
338 if (strncmp(kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) != 0) continue;
340 dbuf = tdb_fetch(tdb_forms, kbuf);
341 if (!dbuf.dptr) continue;
343 fstrcpy(form.name, kbuf.dptr+strlen(FORMS_PREFIX));
344 ret = tdb_unpack(dbuf.dptr, dbuf.dsize, "dddddddd",
345 &i, &form.flag, &form.width, &form.length, &form.left,
346 &form.top, &form.right, &form.bottom);
347 SAFE_FREE(dbuf.dptr);
348 if (ret != dbuf.dsize) continue;
350 tl = Realloc(*list, sizeof(nt_forms_struct)*(n+1));
352 DEBUG(0,("get_ntforms: Realloc fail.\n"));
364 /****************************************************************************
365 write a form struct list
366 ****************************************************************************/
367 int write_ntforms(nt_forms_struct **list, int number)
374 for (i=0;i<number;i++) {
375 /* save index, so list is rebuilt in correct order */
376 len = tdb_pack(buf, sizeof(buf), "dddddddd",
377 i, (*list)[i].flag, (*list)[i].width, (*list)[i].length,
378 (*list)[i].left, (*list)[i].top, (*list)[i].right,
380 if (len > sizeof(buf)) break;
381 slprintf(key, sizeof(key)-1, "%s%s", FORMS_PREFIX, (*list)[i].name);
382 kbuf.dsize = strlen(key)+1;
386 if (tdb_store(tdb_forms, kbuf, dbuf, TDB_REPLACE) != 0) break;
392 /****************************************************************************
393 add a form struct at the end of the list
394 ****************************************************************************/
395 BOOL add_a_form(nt_forms_struct **list, const FORM *form, int *count)
403 * NT tries to add forms even when
404 * they are already in the base
405 * only update the values if already present
410 unistr2_to_ascii(form_name, &form->name, sizeof(form_name)-1);
411 for (n=0; n<*count; n++) {
412 if (!strncmp((*list)[n].name, form_name, strlen(form_name))) {
413 DEBUG(103, ("NT workaround, [%s] already exists\n", form_name));
420 if((tl=Realloc(*list, (n+1)*sizeof(nt_forms_struct))) == NULL) {
421 DEBUG(0,("add_a_form: failed to enlarge forms list!\n"));
425 unistr2_to_ascii((*list)[n].name, &form->name, sizeof((*list)[n].name)-1);
429 (*list)[n].flag=form->flags;
430 (*list)[n].width=form->size_x;
431 (*list)[n].length=form->size_y;
432 (*list)[n].left=form->left;
433 (*list)[n].top=form->top;
434 (*list)[n].right=form->right;
435 (*list)[n].bottom=form->bottom;
440 /****************************************************************************
441 delete a named form struct
442 ****************************************************************************/
443 BOOL delete_a_form(nt_forms_struct **list, UNISTR2 *del_name, int *count, WERROR *ret)
452 unistr2_to_ascii(form_name, del_name, sizeof(form_name)-1);
454 for (n=0; n<*count; n++) {
455 if (!strncmp((*list)[n].name, form_name, strlen(form_name))) {
456 DEBUG(103, ("delete_a_form, [%s] in list\n", form_name));
462 DEBUG(10,("delete_a_form, [%s] not found\n", form_name));
463 *ret = WERR_INVALID_PARAM;
467 slprintf(key, sizeof(key)-1, "%s%s", FORMS_PREFIX, (*list)[n].name);
468 kbuf.dsize = strlen(key)+1;
470 if (tdb_delete(tdb_forms, kbuf) != 0) {
478 /****************************************************************************
480 ****************************************************************************/
481 void update_a_form(nt_forms_struct **list, const FORM *form, int count)
485 unistr2_to_ascii(form_name, &(form->name), sizeof(form_name)-1);
487 DEBUG(106, ("[%s]\n", form_name));
488 for (n=0; n<count; n++)
490 DEBUGADD(106, ("n [%d]:[%s]\n", n, (*list)[n].name));
491 if (!strncmp((*list)[n].name, form_name, strlen(form_name)))
495 if (n==count) return;
497 (*list)[n].flag=form->flags;
498 (*list)[n].width=form->size_x;
499 (*list)[n].length=form->size_y;
500 (*list)[n].left=form->left;
501 (*list)[n].top=form->top;
502 (*list)[n].right=form->right;
503 (*list)[n].bottom=form->bottom;
506 /****************************************************************************
507 get the nt drivers list
509 traverse the database and look-up the matching names
510 ****************************************************************************/
511 int get_ntdrivers(fstring **list, char *architecture, uint32 version)
517 TDB_DATA kbuf, newkey;
519 get_short_archi(short_archi, architecture);
520 slprintf(key, sizeof(key)-1, "%s%s/%d/", DRIVERS_PREFIX, short_archi, version);
522 for (kbuf = tdb_firstkey(tdb_drivers);
524 newkey = tdb_nextkey(tdb_drivers, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
525 if (strncmp(kbuf.dptr, key, strlen(key)) != 0) continue;
527 if((fl = Realloc(*list, sizeof(fstring)*(total+1))) == NULL) {
528 DEBUG(0,("get_ntdrivers: failed to enlarge list!\n"));
533 fstrcpy((*list)[total], kbuf.dptr+strlen(key));
540 /****************************************************************************
541 function to do the mapping between the long architecture name and
543 ****************************************************************************/
544 BOOL get_short_archi(char *short_archi, char *long_archi)
551 struct table archi_table[]=
553 {"Windows 4.0", "WIN40" },
554 {"Windows NT x86", "W32X86" },
555 {"Windows NT R4000", "W32MIPS" },
556 {"Windows NT Alpha_AXP", "W32ALPHA" },
557 {"Windows NT PowerPC", "W32PPC" },
563 DEBUG(107,("Getting architecture dependant directory\n"));
566 } while ( (archi_table[i].long_archi!=NULL ) &&
567 StrCaseCmp(long_archi, archi_table[i].long_archi) );
569 if (archi_table[i].long_archi==NULL) {
570 DEBUGADD(107,("Unknown architecture [%s] !\n", long_archi));
574 StrnCpy (short_archi, archi_table[i].short_archi, strlen(archi_table[i].short_archi));
576 DEBUGADD(108,("index: [%d]\n", i));
577 DEBUGADD(108,("long architecture: [%s]\n", long_archi));
578 DEBUGADD(108,("short architecture: [%s]\n", short_archi));
583 /****************************************************************************
584 Version information in Microsoft files is held in a VS_VERSION_INFO structure.
585 There are two case to be covered here: PE (Portable Executable) and NE (New
586 Executable) files. Both files support the same INFO structure, but PE files
587 store the signature in unicode, and NE files store it as !unicode.
588 returns -1 on error, 1 on version info found, and 0 on no version info found.
589 ****************************************************************************/
591 static int get_file_version(files_struct *fsp, char *fname,uint32 *major, uint32 *minor)
597 if ((buf=malloc(PE_HEADER_SIZE)) == NULL) {
598 DEBUG(0,("get_file_version: PE file [%s] PE Header malloc failed bytes = %d\n",
599 fname, PE_HEADER_SIZE));
603 /* Note: DOS_HEADER_SIZE < malloc'ed PE_HEADER_SIZE */
604 if ((byte_count = vfs_read_data(fsp, buf, DOS_HEADER_SIZE)) < DOS_HEADER_SIZE) {
605 DEBUG(3,("get_file_version: File [%s] DOS header too short, bytes read = %d\n",
607 goto no_version_info;
610 /* Is this really a DOS header? */
611 if (SVAL(buf,DOS_HEADER_MAGIC_OFFSET) != DOS_HEADER_MAGIC) {
612 DEBUG(6,("get_file_version: File [%s] bad DOS magic = 0x%x\n",
613 fname, SVAL(buf,DOS_HEADER_MAGIC_OFFSET)));
614 goto no_version_info;
617 /* Skip OEM header (if any) and the DOS stub to start of Windows header */
618 if (fsp->conn->vfs_ops.lseek(fsp, fsp->fd, SVAL(buf,DOS_HEADER_LFANEW_OFFSET), SEEK_SET) == (SMB_OFF_T)-1) {
619 DEBUG(3,("get_file_version: File [%s] too short, errno = %d\n",
621 /* Assume this isn't an error... the file just looks sort of like a PE/NE file */
622 goto no_version_info;
625 if ((byte_count = vfs_read_data(fsp, buf, PE_HEADER_SIZE)) < PE_HEADER_SIZE) {
626 DEBUG(3,("get_file_version: File [%s] Windows header too short, bytes read = %d\n",
628 /* Assume this isn't an error... the file just looks sort of like a PE/NE file */
629 goto no_version_info;
632 /* The header may be a PE (Portable Executable) or an NE (New Executable) */
633 if (IVAL(buf,PE_HEADER_SIGNATURE_OFFSET) == PE_HEADER_SIGNATURE) {
635 int section_table_bytes;
637 if (SVAL(buf,PE_HEADER_MACHINE_OFFSET) != PE_HEADER_MACHINE_I386) {
638 DEBUG(3,("get_file_version: PE file [%s] wrong machine = 0x%x\n",
639 fname, SVAL(buf,PE_HEADER_MACHINE_OFFSET)));
640 /* At this point, we assume the file is in error. It still could be somthing
641 * else besides a PE file, but it unlikely at this point.
646 /* get the section table */
647 num_sections = SVAL(buf,PE_HEADER_NUMBER_OF_SECTIONS);
648 section_table_bytes = num_sections * PE_HEADER_SECT_HEADER_SIZE;
650 if ((buf=malloc(section_table_bytes)) == NULL) {
651 DEBUG(0,("get_file_version: PE file [%s] section table malloc failed bytes = %d\n",
652 fname, section_table_bytes));
656 if ((byte_count = vfs_read_data(fsp, buf, section_table_bytes)) < section_table_bytes) {
657 DEBUG(3,("get_file_version: PE file [%s] Section header too short, bytes read = %d\n",
662 /* Iterate the section table looking for the resource section ".rsrc" */
663 for (i = 0; i < num_sections; i++) {
664 int sec_offset = i * PE_HEADER_SECT_HEADER_SIZE;
666 if (strcmp(".rsrc", &buf[sec_offset+PE_HEADER_SECT_NAME_OFFSET]) == 0) {
667 int section_pos = IVAL(buf,sec_offset+PE_HEADER_SECT_PTR_DATA_OFFSET);
668 int section_bytes = IVAL(buf,sec_offset+PE_HEADER_SECT_SIZE_DATA_OFFSET);
671 if ((buf=malloc(section_bytes)) == NULL) {
672 DEBUG(0,("get_file_version: PE file [%s] version malloc failed bytes = %d\n",
673 fname, section_bytes));
677 /* Seek to the start of the .rsrc section info */
678 if (fsp->conn->vfs_ops.lseek(fsp, fsp->fd, section_pos, SEEK_SET) == (SMB_OFF_T)-1) {
679 DEBUG(3,("get_file_version: PE file [%s] too short for section info, errno = %d\n",
684 if ((byte_count = vfs_read_data(fsp, buf, section_bytes)) < section_bytes) {
685 DEBUG(3,("get_file_version: PE file [%s] .rsrc section too short, bytes read = %d\n",
690 for (i=0; i<section_bytes-VS_VERSION_INFO_UNICODE_SIZE; i++) {
691 /* Scan for 1st 3 unicoded bytes followed by word aligned magic value */
692 if (buf[i] == 'V' && buf[i+1] == '\0' && buf[i+2] == 'S') {
693 /* Align to next long address */
694 int pos = (i + sizeof(VS_SIGNATURE)*2 + 3) & 0xfffffffc;
696 if (IVAL(buf,pos) == VS_MAGIC_VALUE) {
697 *major = IVAL(buf,pos+VS_MAJOR_OFFSET);
698 *minor = IVAL(buf,pos+VS_MINOR_OFFSET);
700 DEBUG(6,("get_file_version: PE file [%s] Version = %08x:%08x (%d.%d.%d.%d)\n",
701 fname, *major, *minor,
702 (*major>>16)&0xffff, *major&0xffff,
703 (*minor>>16)&0xffff, *minor&0xffff));
712 /* Version info not found, fall back to origin date/time */
713 DEBUG(10,("get_file_version: PE file [%s] has no version info\n", fname));
717 } else if (SVAL(buf,NE_HEADER_SIGNATURE_OFFSET) == NE_HEADER_SIGNATURE) {
718 if (CVAL(buf,NE_HEADER_TARGET_OS_OFFSET) != NE_HEADER_TARGOS_WIN ) {
719 DEBUG(3,("get_file_version: NE file [%s] wrong target OS = 0x%x\n",
720 fname, CVAL(buf,NE_HEADER_TARGET_OS_OFFSET)));
721 /* At this point, we assume the file is in error. It still could be somthing
722 * else besides a NE file, but it unlikely at this point. */
726 /* Allocate a bit more space to speed up things */
728 if ((buf=malloc(VS_NE_BUF_SIZE)) == NULL) {
729 DEBUG(0,("get_file_version: NE file [%s] malloc failed bytes = %d\n",
730 fname, PE_HEADER_SIZE));
734 /* This is a HACK! I got tired of trying to sort through the messy
735 * 'NE' file format. If anyone wants to clean this up please have at
736 * it, but this works. 'NE' files will eventually fade away. JRR */
737 while((byte_count = vfs_read_data(fsp, buf, VS_NE_BUF_SIZE)) > 0) {
738 /* Cover case that should not occur in a well formed 'NE' .dll file */
739 if (byte_count-VS_VERSION_INFO_SIZE <= 0) break;
741 for(i=0; i<byte_count; i++) {
742 /* Fast skip past data that can't possibly match */
743 if (buf[i] != 'V') continue;
745 /* Potential match data crosses buf boundry, move it to beginning
746 * of buf, and fill the buf with as much as it will hold. */
747 if (i>byte_count-VS_VERSION_INFO_SIZE) {
750 memcpy(buf, &buf[i], byte_count-i);
751 if ((bc = vfs_read_data(fsp, &buf[byte_count-i], VS_NE_BUF_SIZE-
752 (byte_count-i))) < 0) {
754 DEBUG(0,("get_file_version: NE file [%s] Read error, errno=%d\n",
759 byte_count = bc + (byte_count - i);
760 if (byte_count<VS_VERSION_INFO_SIZE) break;
765 /* Check that the full signature string and the magic number that
766 * follows exist (not a perfect solution, but the chances that this
767 * occurs in code is, well, remote. Yes I know I'm comparing the 'V'
768 * twice, as it is simpler to read the code. */
769 if (strcmp(&buf[i], VS_SIGNATURE) == 0) {
770 /* Compute skip alignment to next long address */
771 int skip = -(fsp->conn->vfs_ops.lseek(fsp, fsp->fd, 0, SEEK_CUR) - (byte_count - i) +
772 sizeof(VS_SIGNATURE)) & 3;
773 if (IVAL(buf,i+sizeof(VS_SIGNATURE)+skip) != 0xfeef04bd) continue;
775 *major = IVAL(buf,i+sizeof(VS_SIGNATURE)+skip+VS_MAJOR_OFFSET);
776 *minor = IVAL(buf,i+sizeof(VS_SIGNATURE)+skip+VS_MINOR_OFFSET);
777 DEBUG(6,("get_file_version: NE file [%s] Version = %08x:%08x (%d.%d.%d.%d)\n",
778 fname, *major, *minor,
779 (*major>>16)&0xffff, *major&0xffff,
780 (*minor>>16)&0xffff, *minor&0xffff));
787 /* Version info not found, fall back to origin date/time */
788 DEBUG(0,("get_file_version: NE file [%s] Version info not found\n", fname));
793 /* Assume this isn't an error... the file just looks sort of like a PE/NE file */
794 DEBUG(3,("get_file_version: File [%s] unknown file format, signature = 0x%x\n",
795 fname, IVAL(buf,PE_HEADER_SIGNATURE_OFFSET)));
806 /****************************************************************************
807 Drivers for Microsoft systems contain multiple files. Often, multiple drivers
808 share one or more files. During the MS installation process files are checked
809 to insure that only a newer version of a shared file is installed over an
810 older version. There are several possibilities for this comparison. If there
811 is no previous version, the new one is newer (obviously). If either file is
812 missing the version info structure, compare the creation date (on Unix use
813 the modification date). Otherwise chose the numerically larger version number.
814 ****************************************************************************/
815 static int file_version_is_newer(connection_struct *conn, fstring new_file,
818 BOOL use_version = True;
823 time_t new_create_time;
827 time_t old_create_time;
831 files_struct *fsp = NULL;
833 SMB_STRUCT_STAT stat_buf;
837 ZERO_STRUCT(stat_buf);
838 new_create_time = (time_t)0;
839 old_create_time = (time_t)0;
841 /* Get file version info (if available) for previous file (if it exists) */
842 pstrcpy(filepath, old_file);
844 unix_convert(filepath,conn,NULL,&bad_path,&stat_buf);
846 fsp = open_file_shared(conn, filepath, &stat_buf,
847 SET_OPEN_MODE(DOS_OPEN_RDONLY),
848 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
849 0, 0, &access_mode, &action);
851 /* Old file not found, so by definition new file is in fact newer */
852 DEBUG(10,("file_version_is_newer: Can't open old file [%s], errno = %d\n",
857 int ret = get_file_version(fsp, old_file, &old_major, &old_minor);
858 if (ret == -1) goto error_exit;
861 DEBUG(6,("file_version_is_newer: Version info not found [%s], use mod time\n",
864 if (fsp->conn->vfs_ops.fstat(fsp, fsp->fd, &st) == -1) goto error_exit;
865 old_create_time = st.st_mtime;
866 DEBUGADD(6,("file_version_is_newer: mod time = %ld sec\n", old_create_time));
869 close_file(fsp, True);
871 /* Get file version info (if available) for new file */
872 pstrcpy(filepath, new_file);
873 unix_convert(filepath,conn,NULL,&bad_path,&stat_buf);
875 fsp = open_file_shared(conn, filepath, &stat_buf,
876 SET_OPEN_MODE(DOS_OPEN_RDONLY),
877 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
878 0, 0, &access_mode, &action);
880 /* New file not found, this shouldn't occur if the caller did its job */
881 DEBUG(3,("file_version_is_newer: Can't open new file [%s], errno = %d\n",
886 int ret = get_file_version(fsp, new_file, &new_major, &new_minor);
887 if (ret == -1) goto error_exit;
890 DEBUG(6,("file_version_is_newer: Version info not found [%s], use mod time\n",
893 if (fsp->conn->vfs_ops.fstat(fsp, fsp->fd, &st) == -1) goto error_exit;
894 new_create_time = st.st_mtime;
895 DEBUGADD(6,("file_version_is_newer: mod time = %ld sec\n", new_create_time));
898 close_file(fsp, True);
901 /* Compare versions and choose the larger version number */
902 if (new_major > old_major ||
903 (new_major == old_major && new_minor > old_minor)) {
905 DEBUG(6,("file_version_is_newer: Replacing [%s] with [%s]\n", old_file, new_file));
909 DEBUG(6,("file_version_is_newer: Leaving [%s] unchanged\n", old_file));
914 /* Compare modification time/dates and choose the newest time/date */
915 if (new_create_time > old_create_time) {
916 DEBUG(6,("file_version_is_newer: Replacing [%s] with [%s]\n", old_file, new_file));
920 DEBUG(6,("file_version_is_newer: Leaving [%s] unchanged\n", old_file));
927 close_file(fsp, True);
931 /****************************************************************************
932 Determine the correct cVersion associated with an architecture and driver
933 ****************************************************************************/
934 static uint32 get_correct_cversion(fstring architecture, fstring driverpath_in,
935 struct current_user *user, WERROR *perr)
943 files_struct *fsp = NULL;
946 connection_struct *conn;
950 *perr = WERR_INVALID_PARAM;
952 /* If architecture is Windows 95/98/ME, the version is always 0. */
953 if (strcmp(architecture, "WIN40") == 0) {
954 DEBUG(10,("get_correct_cversion: Driver is Win9x, cversion = 0\n"));
959 /* connect to the print$ share under the same account as the user connected to the rpc pipe */
960 /* Null password is ok - we are already an authenticated user... */
961 null_pw = data_blob(NULL, 0);
964 conn = make_connection("print$", null_pw, "A:", user->vuid, &nt_status);
968 DEBUG(0,("get_correct_cversion: Unable to connect\n"));
969 *perr = ntstatus_to_werror(nt_status);
973 /* We are temporarily becoming the connection user. */
974 if (!become_user(conn, conn->vuid)) {
975 DEBUG(0,("get_correct_cversion: Can't become user!\n"));
976 *perr = WERR_ACCESS_DENIED;
980 /* Open the driver file (Portable Executable format) and determine the
981 * deriver the cversion. */
982 slprintf(driverpath, sizeof(driverpath)-1, "%s/%s", architecture, driverpath_in);
984 unix_convert(driverpath,conn,NULL,&bad_path,&st);
986 fsp = open_file_shared(conn, driverpath, &st,
987 SET_OPEN_MODE(DOS_OPEN_RDONLY),
988 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
989 0, 0, &access_mode, &action);
991 DEBUG(3,("get_correct_cversion: Can't open file [%s], errno = %d\n",
993 *perr = WERR_ACCESS_DENIED;
999 int ret = get_file_version(fsp, driverpath, &major, &minor);
1000 if (ret == -1) goto error_exit;
1003 DEBUG(6,("get_correct_cversion: Version info not found [%s]\n", driverpath));
1008 * This is a Microsoft'ism. See references in MSDN to VER_FILEVERSION
1009 * for more details. Version in this case is not just the version of the
1010 * file, but the version in the sense of kernal mode (2) vs. user mode
1011 * (3) drivers. Other bits of the version fields are the version info.
1014 cversion = major & 0x0000ffff;
1016 case 2: /* WinNT drivers */
1017 case 3: /* Win2K drivers */
1021 DEBUG(6,("get_correct_cversion: cversion invalid [%s] cversion = %d\n",
1022 driverpath, cversion));
1026 DEBUG(10,("get_correct_cversion: Version info found [%s] major = 0x%x minor = 0x%x\n",
1027 driverpath, major, minor));
1030 DEBUG(10,("get_correct_cversion: Driver file [%s] cversion = %d\n",
1031 driverpath, cversion));
1033 close_file(fsp, True);
1034 close_cnum(conn, user->vuid);
1042 close_file(fsp, True);
1044 close_cnum(conn, user->vuid);
1049 /****************************************************************************
1050 ****************************************************************************/
1051 static WERROR clean_up_driver_struct_level_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver,
1052 struct current_user *user)
1054 fstring architecture;
1060 /* clean up the driver name.
1061 * we can get .\driver.dll
1062 * or worse c:\windows\system\driver.dll !
1064 /* using an intermediate string to not have overlaping memcpy()'s */
1065 if ((p = strrchr(driver->driverpath,'\\')) != NULL) {
1066 fstrcpy(new_name, p+1);
1067 fstrcpy(driver->driverpath, new_name);
1070 if ((p = strrchr(driver->datafile,'\\')) != NULL) {
1071 fstrcpy(new_name, p+1);
1072 fstrcpy(driver->datafile, new_name);
1075 if ((p = strrchr(driver->configfile,'\\')) != NULL) {
1076 fstrcpy(new_name, p+1);
1077 fstrcpy(driver->configfile, new_name);
1080 if ((p = strrchr(driver->helpfile,'\\')) != NULL) {
1081 fstrcpy(new_name, p+1);
1082 fstrcpy(driver->helpfile, new_name);
1085 if (driver->dependentfiles) {
1086 for (i=0; *driver->dependentfiles[i]; i++) {
1087 if ((p = strrchr(driver->dependentfiles[i],'\\')) != NULL) {
1088 fstrcpy(new_name, p+1);
1089 fstrcpy(driver->dependentfiles[i], new_name);
1094 get_short_archi(architecture, driver->environment);
1096 /* jfm:7/16/2000 the client always sends the cversion=0.
1097 * The server should check which version the driver is by reading
1098 * the PE header of driver->driverpath.
1100 * For Windows 95/98 the version is 0 (so the value sent is correct)
1101 * For Windows NT (the architecture doesn't matter)
1102 * NT 3.1: cversion=0
1103 * NT 3.5/3.51: cversion=1
1107 if ((driver->cversion = get_correct_cversion( architecture,
1108 driver->driverpath, user, &err)) == -1)
1114 /****************************************************************************
1115 ****************************************************************************/
1116 static WERROR clean_up_driver_struct_level_6(NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver,
1117 struct current_user *user)
1119 fstring architecture;
1125 /* clean up the driver name.
1126 * we can get .\driver.dll
1127 * or worse c:\windows\system\driver.dll !
1129 /* using an intermediate string to not have overlaping memcpy()'s */
1130 if ((p = strrchr(driver->driverpath,'\\')) != NULL) {
1131 fstrcpy(new_name, p+1);
1132 fstrcpy(driver->driverpath, new_name);
1135 if ((p = strrchr(driver->datafile,'\\')) != NULL) {
1136 fstrcpy(new_name, p+1);
1137 fstrcpy(driver->datafile, new_name);
1140 if ((p = strrchr(driver->configfile,'\\')) != NULL) {
1141 fstrcpy(new_name, p+1);
1142 fstrcpy(driver->configfile, new_name);
1145 if ((p = strrchr(driver->helpfile,'\\')) != NULL) {
1146 fstrcpy(new_name, p+1);
1147 fstrcpy(driver->helpfile, new_name);
1150 if (driver->dependentfiles) {
1151 for (i=0; *driver->dependentfiles[i]; i++) {
1152 if ((p = strrchr(driver->dependentfiles[i],'\\')) != NULL) {
1153 fstrcpy(new_name, p+1);
1154 fstrcpy(driver->dependentfiles[i], new_name);
1159 get_short_archi(architecture, driver->environment);
1161 /* jfm:7/16/2000 the client always sends the cversion=0.
1162 * The server should check which version the driver is by reading
1163 * the PE header of driver->driverpath.
1165 * For Windows 95/98 the version is 0 (so the value sent is correct)
1166 * For Windows NT (the architecture doesn't matter)
1167 * NT 3.1: cversion=0
1168 * NT 3.5/3.51: cversion=1
1172 if ((driver->version = get_correct_cversion(architecture,
1173 driver->driverpath, user, &err)) == -1)
1179 /****************************************************************************
1180 ****************************************************************************/
1181 WERROR clean_up_driver_struct(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract,
1182 uint32 level, struct current_user *user)
1187 NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver;
1188 driver=driver_abstract.info_3;
1189 return clean_up_driver_struct_level_3(driver, user);
1193 NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver;
1194 driver=driver_abstract.info_6;
1195 return clean_up_driver_struct_level_6(driver, user);
1198 return WERR_INVALID_PARAM;
1202 /****************************************************************************
1203 This function sucks and should be replaced. JRA.
1204 ****************************************************************************/
1206 static void convert_level_6_to_level3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *dst, NT_PRINTER_DRIVER_INFO_LEVEL_6 *src)
1208 dst->cversion = src->version;
1210 fstrcpy( dst->name, src->name);
1211 fstrcpy( dst->environment, src->environment);
1212 fstrcpy( dst->driverpath, src->driverpath);
1213 fstrcpy( dst->datafile, src->datafile);
1214 fstrcpy( dst->configfile, src->configfile);
1215 fstrcpy( dst->helpfile, src->helpfile);
1216 fstrcpy( dst->monitorname, src->monitorname);
1217 fstrcpy( dst->defaultdatatype, src->defaultdatatype);
1218 dst->dependentfiles = src->dependentfiles;
1221 #if 0 /* Debugging function */
1223 static char* ffmt(unsigned char *c){
1225 static char ffmt_str[17];
1227 for (i=0; i<16; i++) {
1228 if ((c[i] < ' ') || (c[i] > '~'))
1239 /****************************************************************************
1240 ****************************************************************************/
1241 BOOL move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract, uint32 level,
1242 struct current_user *user, WERROR *perr)
1244 NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver;
1245 NT_PRINTER_DRIVER_INFO_LEVEL_3 converted_driver;
1246 fstring architecture;
1251 connection_struct *conn;
1259 driver=driver_abstract.info_3;
1260 else if (level==6) {
1261 convert_level_6_to_level3(&converted_driver, driver_abstract.info_6);
1262 driver = &converted_driver;
1264 DEBUG(0,("move_driver_to_download_area: Unknown info level (%u)\n", (unsigned int)level ));
1268 get_short_archi(architecture, driver->environment);
1270 /* connect to the print$ share under the same account as the user connected to the rpc pipe */
1271 /* Null password is ok - we are already an authenticated user... */
1272 null_pw = data_blob(NULL, 0);
1273 conn = make_connection("print$", null_pw, "A:", user->vuid, &nt_status);
1276 DEBUG(0,("move_driver_to_download_area: Unable to connect\n"));
1277 *perr = ntstatus_to_werror(nt_status);
1282 * Save who we are - we are temporarily becoming the connection user.
1287 if (!become_user(conn, conn->vuid)) {
1288 DEBUG(0,("move_driver_to_download_area: Can't become user!\n"));
1294 * make the directories version and version\driver_name
1295 * under the architecture directory.
1297 DEBUG(5,("Creating first directory\n"));
1298 slprintf(new_dir, sizeof(new_dir)-1, "%s/%d", architecture, driver->cversion);
1299 mkdir_internal(conn, new_dir);
1301 /* For each driver file, archi\filexxx.yyy, if there is a duplicate file
1302 * listed for this driver which has already been moved, skip it (note:
1303 * drivers may list the same file name several times. Then check if the
1304 * file already exists in archi\cversion\, if so, check that the version
1305 * info (or time stamps if version info is unavailable) is newer (or the
1306 * date is later). If it is, move it to archi\cversion\filexxx.yyy.
1307 * Otherwise, delete the file.
1309 * If a file is not moved to archi\cversion\ because of an error, all the
1310 * rest of the 'unmoved' driver files are removed from archi\. If one or
1311 * more of the driver's files was already moved to archi\cversion\, it
1312 * potentially leaves the driver in a partially updated state. Version
1313 * trauma will most likely occur if an client attempts to use any printer
1314 * bound to the driver. Perhaps a rewrite to make sure the moves can be
1315 * done is appropriate... later JRR
1318 DEBUG(5,("Moving files now !\n"));
1320 if (driver->driverpath && strlen(driver->driverpath)) {
1321 slprintf(new_name, sizeof(new_name)-1, "%s/%s", architecture, driver->driverpath);
1322 slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->driverpath);
1323 if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
1325 status = rename_internals(conn, new_name, old_name, True);
1326 if (!NT_STATUS_IS_OK(status)) {
1327 DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
1328 new_name, old_name));
1329 *perr = ntstatus_to_werror(status);
1330 unlink_internals(conn, 0, new_name);
1335 unlink_internals(conn, 0, new_name);
1338 if (driver->datafile && strlen(driver->datafile)) {
1339 if (!strequal(driver->datafile, driver->driverpath)) {
1340 slprintf(new_name, sizeof(new_name)-1, "%s/%s", architecture, driver->datafile);
1341 slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->datafile);
1342 if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
1344 status = rename_internals(conn, new_name, old_name, True);
1345 if (!NT_STATUS_IS_OK(status)) {
1346 DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
1347 new_name, old_name));
1348 *perr = ntstatus_to_werror(status);
1349 unlink_internals(conn, 0, new_name);
1354 unlink_internals(conn, 0, new_name);
1358 if (driver->configfile && strlen(driver->configfile)) {
1359 if (!strequal(driver->configfile, driver->driverpath) &&
1360 !strequal(driver->configfile, driver->datafile)) {
1361 slprintf(new_name, sizeof(new_name)-1, "%s/%s", architecture, driver->configfile);
1362 slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->configfile);
1363 if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
1365 status = rename_internals(conn, new_name, old_name, True);
1366 if (!NT_STATUS_IS_OK(status)) {
1367 DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
1368 new_name, old_name));
1369 *perr = ntstatus_to_werror(status);
1370 unlink_internals(conn, 0, new_name);
1375 unlink_internals(conn, 0, new_name);
1379 if (driver->helpfile && strlen(driver->helpfile)) {
1380 if (!strequal(driver->helpfile, driver->driverpath) &&
1381 !strequal(driver->helpfile, driver->datafile) &&
1382 !strequal(driver->helpfile, driver->configfile)) {
1383 slprintf(new_name, sizeof(new_name)-1, "%s/%s", architecture, driver->helpfile);
1384 slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->helpfile);
1385 if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
1387 status = rename_internals(conn, new_name, old_name, True);
1388 if (!NT_STATUS_IS_OK(status)) {
1389 DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
1390 new_name, old_name));
1391 *perr = ntstatus_to_werror(status);
1392 unlink_internals(conn, 0, new_name);
1397 unlink_internals(conn, 0, new_name);
1401 if (driver->dependentfiles) {
1402 for (i=0; *driver->dependentfiles[i]; i++) {
1403 if (!strequal(driver->dependentfiles[i], driver->driverpath) &&
1404 !strequal(driver->dependentfiles[i], driver->datafile) &&
1405 !strequal(driver->dependentfiles[i], driver->configfile) &&
1406 !strequal(driver->dependentfiles[i], driver->helpfile)) {
1408 for (j=0; j < i; j++) {
1409 if (strequal(driver->dependentfiles[i], driver->dependentfiles[j])) {
1414 slprintf(new_name, sizeof(new_name)-1, "%s/%s", architecture, driver->dependentfiles[i]);
1415 slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->dependentfiles[i]);
1416 if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
1418 status = rename_internals(conn, new_name, old_name, True);
1419 if (!NT_STATUS_IS_OK(status)) {
1420 DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
1421 new_name, old_name));
1422 *perr = ntstatus_to_werror(status);
1423 unlink_internals(conn, 0, new_name);
1428 unlink_internals(conn, 0, new_name);
1434 close_cnum(conn, user->vuid);
1437 return ver == -1 ? False : True;
1440 /****************************************************************************
1441 ****************************************************************************/
1442 static uint32 add_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver)
1445 fstring architecture;
1451 TDB_DATA kbuf, dbuf;
1453 get_short_archi(architecture, driver->environment);
1455 /* The names are relative. We store them in the form: \print$\arch\version\driver.xxx
1456 * \\server is added in the rpc server layer.
1457 * It does make sense to NOT store the server's name in the printer TDB.
1460 slprintf(directory, sizeof(directory)-1, "\\print$\\%s\\%d\\", architecture, driver->cversion);
1462 /* .inf files do not always list a file for each of the four standard files.
1463 * Don't prepend a path to a null filename, or client claims:
1464 * "The server on which the printer resides does not have a suitable
1465 * <printer driver name> printer driver installed. Click OK if you
1466 * wish to install the driver on your local machine."
1468 if (strlen(driver->driverpath)) {
1469 fstrcpy(temp_name, driver->driverpath);
1470 slprintf(driver->driverpath, sizeof(driver->driverpath)-1, "%s%s", directory, temp_name);
1473 if (strlen(driver->datafile)) {
1474 fstrcpy(temp_name, driver->datafile);
1475 slprintf(driver->datafile, sizeof(driver->datafile)-1, "%s%s", directory, temp_name);
1478 if (strlen(driver->configfile)) {
1479 fstrcpy(temp_name, driver->configfile);
1480 slprintf(driver->configfile, sizeof(driver->configfile)-1, "%s%s", directory, temp_name);
1483 if (strlen(driver->helpfile)) {
1484 fstrcpy(temp_name, driver->helpfile);
1485 slprintf(driver->helpfile, sizeof(driver->helpfile)-1, "%s%s", directory, temp_name);
1488 if (driver->dependentfiles) {
1489 for (i=0; *driver->dependentfiles[i]; i++) {
1490 fstrcpy(temp_name, driver->dependentfiles[i]);
1491 slprintf(driver->dependentfiles[i], sizeof(driver->dependentfiles[i])-1, "%s%s", directory, temp_name);
1495 slprintf(key, sizeof(key)-1, "%s%s/%d/%s", DRIVERS_PREFIX, architecture, driver->cversion, driver->name);
1497 DEBUG(5,("add_a_printer_driver_3: Adding driver with key %s\n", key ));
1504 len += tdb_pack(buf+len, buflen-len, "dffffffff",
1507 driver->environment,
1512 driver->monitorname,
1513 driver->defaultdatatype);
1515 if (driver->dependentfiles) {
1516 for (i=0; *driver->dependentfiles[i]; i++) {
1517 len += tdb_pack(buf+len, buflen-len, "f",
1518 driver->dependentfiles[i]);
1522 if (len != buflen) {
1525 tb = (char *)Realloc(buf, len);
1527 DEBUG(0,("add_a_printer_driver_3: failed to enlarge buffer\n!"));
1538 kbuf.dsize = strlen(key)+1;
1542 ret = tdb_store(tdb_drivers, kbuf, dbuf, TDB_REPLACE);
1546 DEBUG(0,("add_a_printer_driver_3: Adding driver with key %s failed.\n", key ));
1552 /****************************************************************************
1553 ****************************************************************************/
1554 static uint32 add_a_printer_driver_6(NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver)
1556 NT_PRINTER_DRIVER_INFO_LEVEL_3 info3;
1559 info3.cversion = driver->version;
1560 fstrcpy(info3.name,driver->name);
1561 fstrcpy(info3.environment,driver->environment);
1562 fstrcpy(info3.driverpath,driver->driverpath);
1563 fstrcpy(info3.datafile,driver->datafile);
1564 fstrcpy(info3.configfile,driver->configfile);
1565 fstrcpy(info3.helpfile,driver->helpfile);
1566 fstrcpy(info3.monitorname,driver->monitorname);
1567 fstrcpy(info3.defaultdatatype,driver->defaultdatatype);
1568 info3.dependentfiles = driver->dependentfiles;
1570 return add_a_printer_driver_3(&info3);
1574 /****************************************************************************
1575 ****************************************************************************/
1576 static WERROR get_a_printer_driver_3_default(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, fstring in_prt, fstring in_arch)
1578 NT_PRINTER_DRIVER_INFO_LEVEL_3 info;
1582 fstrcpy(info.name, in_prt);
1583 fstrcpy(info.defaultdatatype, "RAW");
1585 fstrcpy(info.driverpath, "");
1586 fstrcpy(info.datafile, "");
1587 fstrcpy(info.configfile, "");
1588 fstrcpy(info.helpfile, "");
1590 if ((info.dependentfiles=(fstring *)malloc(2*sizeof(fstring))) == NULL)
1593 memset(info.dependentfiles, '\0', 2*sizeof(fstring));
1594 fstrcpy(info.dependentfiles[0], "");
1596 *info_ptr = memdup(&info, sizeof(info));
1601 /****************************************************************************
1602 ****************************************************************************/
1603 static WERROR get_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, fstring in_prt, fstring in_arch, uint32 version)
1605 NT_PRINTER_DRIVER_INFO_LEVEL_3 driver;
1606 TDB_DATA kbuf, dbuf;
1607 fstring architecture;
1612 ZERO_STRUCT(driver);
1614 get_short_archi(architecture, in_arch);
1616 DEBUG(8,("get_a_printer_driver_3: [%s%s/%d/%s]\n", DRIVERS_PREFIX, architecture, version, in_prt));
1618 slprintf(key, sizeof(key)-1, "%s%s/%d/%s", DRIVERS_PREFIX, architecture, version, in_prt);
1621 kbuf.dsize = strlen(key)+1;
1623 dbuf = tdb_fetch(tdb_drivers, kbuf);
1625 if (!dbuf.dptr) return get_a_printer_driver_3_default(info_ptr, in_prt, in_arch);
1627 if (!dbuf.dptr) return WERR_ACCESS_DENIED;
1629 len += tdb_unpack(dbuf.dptr, dbuf.dsize, "dffffffff",
1638 driver.defaultdatatype);
1641 while (len < dbuf.dsize) {
1644 tddfs = (fstring *)Realloc(driver.dependentfiles,
1645 sizeof(fstring)*(i+2));
1646 if (tddfs == NULL) {
1647 DEBUG(0,("get_a_printer_driver_3: failed to enlarge buffer!\n"));
1650 else driver.dependentfiles = tddfs;
1652 len += tdb_unpack(dbuf.dptr+len, dbuf.dsize-len, "f",
1653 &driver.dependentfiles[i]);
1656 if (driver.dependentfiles != NULL)
1657 fstrcpy(driver.dependentfiles[i], "");
1659 SAFE_FREE(dbuf.dptr);
1661 if (len != dbuf.dsize) {
1662 SAFE_FREE(driver.dependentfiles);
1664 return get_a_printer_driver_3_default(info_ptr, in_prt, in_arch);
1667 *info_ptr = (NT_PRINTER_DRIVER_INFO_LEVEL_3 *)memdup(&driver, sizeof(driver));
1672 /****************************************************************************
1673 ****************************************************************************/
1674 uint32 get_a_printer_driver_9x_compatible(pstring line, fstring model)
1676 NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3;
1682 slprintf(key, sizeof(key)-1, "%s%s/%d/%s", DRIVERS_PREFIX, "WIN40", 0, model);
1683 DEBUG(10,("driver key: [%s]\n", key));
1686 kbuf.dsize = strlen(key)+1;
1687 if (!tdb_exists(tdb_drivers, kbuf)) return False;
1690 get_a_printer_driver_3(&info3, model, "Windows 4.0", 0);
1692 DEBUGADD(10,("info3->name [%s]\n", info3->name));
1693 DEBUGADD(10,("info3->datafile [%s]\n", info3->datafile));
1694 DEBUGADD(10,("info3->helpfile [%s]\n", info3->helpfile));
1695 DEBUGADD(10,("info3->monitorname [%s]\n", info3->monitorname));
1696 DEBUGADD(10,("info3->defaultdatatype [%s]\n", info3->defaultdatatype));
1697 for (i=0; info3->dependentfiles && *info3->dependentfiles[i]; i++) {
1698 DEBUGADD(10,("info3->dependentfiles [%s]\n", info3->dependentfiles[i]));
1700 DEBUGADD(10,("info3->environment [%s]\n", info3->environment));
1701 DEBUGADD(10,("info3->driverpath [%s]\n", info3->driverpath));
1702 DEBUGADD(10,("info3->configfile [%s]\n", info3->configfile));
1704 /*pstrcat(line, info3->name); pstrcat(line, ":");*/
1705 trim_string(info3->configfile, "\\print$\\WIN40\\0\\", 0);
1706 pstrcat(line, info3->configfile);
1708 trim_string(info3->datafile, "\\print$\\WIN40\\0\\", 0);
1709 pstrcat(line, info3->datafile);
1711 trim_string(info3->helpfile, "\\print$\\WIN40\\0\\", 0);
1712 pstrcat(line, info3->helpfile);
1714 trim_string(info3->monitorname, "\\print$\\WIN40\\0\\", 0);
1715 pstrcat(line, info3->monitorname);
1717 pstrcat(line, "RAW"); /*info3->defaultdatatype);*/
1720 for (i=0; info3->dependentfiles &&
1721 *info3->dependentfiles[i]; i++) {
1722 if (i) pstrcat(line, ","); /* don't end in a "," */
1723 trim_string(info3->dependentfiles[i], "\\print$\\WIN40\\0\\", 0);
1724 pstrcat(line, info3->dependentfiles[i]);
1732 /****************************************************************************
1733 debugging function, dump at level 6 the struct in the logs
1734 ****************************************************************************/
1735 static uint32 dump_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
1738 NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3;
1741 DEBUG(106,("Dumping printer driver at level [%d]\n", level));
1747 if (driver.info_3 == NULL)
1750 info3=driver.info_3;
1752 DEBUGADD(106,("version:[%d]\n", info3->cversion));
1753 DEBUGADD(106,("name:[%s]\n", info3->name));
1754 DEBUGADD(106,("environment:[%s]\n", info3->environment));
1755 DEBUGADD(106,("driverpath:[%s]\n", info3->driverpath));
1756 DEBUGADD(106,("datafile:[%s]\n", info3->datafile));
1757 DEBUGADD(106,("configfile:[%s]\n", info3->configfile));
1758 DEBUGADD(106,("helpfile:[%s]\n", info3->helpfile));
1759 DEBUGADD(106,("monitorname:[%s]\n", info3->monitorname));
1760 DEBUGADD(106,("defaultdatatype:[%s]\n", info3->defaultdatatype));
1762 for (i=0; info3->dependentfiles &&
1763 *info3->dependentfiles[i]; i++) {
1764 DEBUGADD(106,("dependentfile:[%s]\n",
1765 info3->dependentfiles[i]));
1772 DEBUGADD(1,("Level not implemented\n"));
1780 /****************************************************************************
1781 ****************************************************************************/
1782 static int pack_devicemode(NT_DEVICEMODE *nt_devmode, char *buf, int buflen)
1786 len += tdb_pack(buf+len, buflen-len, "p", nt_devmode);
1788 if (!nt_devmode) return len;
1790 len += tdb_pack(buf+len, buflen-len, "ffwwwwwwwwwwwwwwwwwwddddddddddddddp",
1791 nt_devmode->devicename,
1792 nt_devmode->formname,
1794 nt_devmode->specversion,
1795 nt_devmode->driverversion,
1797 nt_devmode->driverextra,
1798 nt_devmode->orientation,
1799 nt_devmode->papersize,
1800 nt_devmode->paperlength,
1801 nt_devmode->paperwidth,
1804 nt_devmode->defaultsource,
1805 nt_devmode->printquality,
1808 nt_devmode->yresolution,
1809 nt_devmode->ttoption,
1810 nt_devmode->collate,
1811 nt_devmode->logpixels,
1814 nt_devmode->bitsperpel,
1815 nt_devmode->pelswidth,
1816 nt_devmode->pelsheight,
1817 nt_devmode->displayflags,
1818 nt_devmode->displayfrequency,
1819 nt_devmode->icmmethod,
1820 nt_devmode->icmintent,
1821 nt_devmode->mediatype,
1822 nt_devmode->dithertype,
1823 nt_devmode->reserved1,
1824 nt_devmode->reserved2,
1825 nt_devmode->panningwidth,
1826 nt_devmode->panningheight,
1827 nt_devmode->private);
1830 if (nt_devmode->private) {
1831 len += tdb_pack(buf+len, buflen-len, "B",
1832 nt_devmode->driverextra,
1833 nt_devmode->private);
1836 DEBUG(8,("Packed devicemode [%s]\n", nt_devmode->formname));
1841 /****************************************************************************
1842 ****************************************************************************/
1843 static int pack_specifics(NT_PRINTER_PARAM *param, char *buf, int buflen)
1847 while (param != NULL) {
1848 len += tdb_pack(buf+len, buflen-len, "pfdB",
1857 len += tdb_pack(buf+len, buflen-len, "p", param);
1863 /****************************************************************************
1864 delete a printer - this just deletes the printer info file, any open
1865 handles are not affected
1866 ****************************************************************************/
1867 uint32 del_a_printer(char *sharename)
1872 slprintf(key, sizeof(key)-1, "%s%s", PRINTERS_PREFIX, sharename);
1875 kbuf.dsize=strlen(key)+1;
1877 tdb_delete(tdb_printers, kbuf);
1881 /* FIXME!!! Reorder so this forward declaration is not necessary --jerry */
1882 static WERROR get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **, fstring);
1883 static void free_nt_printer_info_level_2(NT_PRINTER_INFO_LEVEL_2 **);
1884 /****************************************************************************
1885 ****************************************************************************/
1886 static WERROR update_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info)
1892 TDB_DATA kbuf, dbuf;
1895 * in addprinter: no servername and the printer is the name
1896 * in setprinter: servername is \\server
1897 * and printer is \\server\\printer
1899 * Samba manages only local printers.
1900 * we currently don't support things like path=\\other_server\printer
1903 if (info->servername[0]!='\0') {
1904 trim_string(info->printername, info->servername, NULL);
1905 trim_string(info->printername, "\\", NULL);
1906 info->servername[0]='\0';
1910 * JFM: one day I'll forget.
1911 * below that's info->portname because that's the SAMBA sharename
1912 * and I made NT 'thinks' it's the portname
1913 * the info->sharename is the thing you can name when you add a printer
1914 * that's the short-name when you create shared printer for 95/98
1915 * So I've made a limitation in SAMBA: you can only have 1 printer model
1916 * behind a SAMBA share.
1924 len += tdb_pack(buf+len, buflen-len, "dddddddddddfffffPfffff",
1927 info->default_priority,
1944 info->printprocessor,
1948 len += pack_devicemode(info->devmode, buf+len, buflen-len);
1950 len += pack_specifics(info->specific, buf+len, buflen-len);
1952 if (buflen != len) {
1955 tb = (char *)Realloc(buf, len);
1957 DEBUG(0,("update_a_printer_2: failed to enlarge buffer!\n"));
1967 slprintf(key, sizeof(key)-1, "%s%s", PRINTERS_PREFIX, info->sharename);
1970 kbuf.dsize = strlen(key)+1;
1974 ret = (tdb_store(tdb_printers, kbuf, dbuf, TDB_REPLACE) == 0? WERR_OK : WERR_NOMEM);
1977 if (!W_ERROR_IS_OK(ret))
1978 DEBUG(8, ("error updating printer to tdb on disk\n"));
1982 DEBUG(8,("packed printer [%s] with driver [%s] portname=[%s] len=%d\n",
1983 info->sharename, info->drivername, info->portname, len));
1989 /****************************************************************************
1990 ****************************************************************************/
1991 void add_a_specific_param(NT_PRINTER_INFO_LEVEL_2 *info_2, NT_PRINTER_PARAM **param)
1993 NT_PRINTER_PARAM *current;
1995 DEBUG(108,("add_a_specific_param\n"));
1997 (*param)->next=NULL;
1999 if (info_2->specific == NULL)
2001 info_2->specific=*param;
2005 current=info_2->specific;
2006 while (current->next != NULL) {
2007 current=current->next;
2009 current->next=*param;
2015 /****************************************************************************
2016 ****************************************************************************/
2017 BOOL unlink_specific_param_if_exist(NT_PRINTER_INFO_LEVEL_2 *info_2, NT_PRINTER_PARAM *param)
2019 NT_PRINTER_PARAM *current;
2020 NT_PRINTER_PARAM *previous;
2022 current=info_2->specific;
2025 if (current==NULL) return (False);
2027 if ( !strcmp(current->value, param->value) &&
2028 (strlen(current->value)==strlen(param->value)) ) {
2029 DEBUG(109,("deleting first value\n"));
2030 info_2->specific=current->next;
2031 SAFE_FREE(current->data);
2033 DEBUG(109,("deleted first value\n"));
2037 current=previous->next;
2039 while ( current!=NULL ) {
2040 if (!strcmp(current->value, param->value) &&
2041 strlen(current->value)==strlen(param->value) ) {
2042 DEBUG(109,("deleting current value\n"));
2043 previous->next=current->next;
2044 SAFE_FREE(current->data);
2046 DEBUG(109,("deleted current value\n"));
2050 previous=previous->next;
2051 current=current->next;
2056 /****************************************************************************
2057 Clean up and deallocate a (maybe partially) allocated NT_PRINTER_PARAM.
2058 ****************************************************************************/
2059 void free_nt_printer_param(NT_PRINTER_PARAM **param_ptr)
2061 NT_PRINTER_PARAM *param = *param_ptr;
2066 DEBUG(106,("free_nt_printer_param: deleting param [%s]\n", param->value));
2068 SAFE_FREE(param->data);
2069 SAFE_FREE(*param_ptr);
2072 /****************************************************************************
2073 Malloc and return an NT devicemode.
2074 ****************************************************************************/
2076 NT_DEVICEMODE *construct_nt_devicemode(const fstring default_devicename)
2079 * should I init this ones ???
2080 nt_devmode->devicename
2084 NT_DEVICEMODE *nt_devmode = (NT_DEVICEMODE *)malloc(sizeof(NT_DEVICEMODE));
2086 if (nt_devmode == NULL) {
2087 DEBUG(0,("construct_nt_devicemode: malloc fail.\n"));
2091 ZERO_STRUCTP(nt_devmode);
2093 safe_strcpy(adevice, default_devicename, sizeof(adevice));
2094 fstrcpy(nt_devmode->devicename, adevice);
2096 fstrcpy(nt_devmode->formname, "Letter");
2098 nt_devmode->specversion = 0x0401;
2099 nt_devmode->driverversion = 0x0400;
2100 nt_devmode->size = 0x00DC;
2101 nt_devmode->driverextra = 0x0000;
2102 nt_devmode->fields = FORMNAME | TTOPTION | PRINTQUALITY |
2103 DEFAULTSOURCE | COPIES | SCALE |
2104 PAPERSIZE | ORIENTATION;
2105 nt_devmode->orientation = 1;
2106 nt_devmode->papersize = PAPER_LETTER;
2107 nt_devmode->paperlength = 0;
2108 nt_devmode->paperwidth = 0;
2109 nt_devmode->scale = 0x64;
2110 nt_devmode->copies = 1;
2111 nt_devmode->defaultsource = BIN_FORMSOURCE;
2112 nt_devmode->printquality = RES_HIGH; /* 0x0258 */
2113 nt_devmode->color = COLOR_MONOCHROME;
2114 nt_devmode->duplex = DUP_SIMPLEX;
2115 nt_devmode->yresolution = 0;
2116 nt_devmode->ttoption = TT_SUBDEV;
2117 nt_devmode->collate = COLLATE_FALSE;
2118 nt_devmode->icmmethod = 0;
2119 nt_devmode->icmintent = 0;
2120 nt_devmode->mediatype = 0;
2121 nt_devmode->dithertype = 0;
2123 /* non utilisés par un driver d'imprimante */
2124 nt_devmode->logpixels = 0;
2125 nt_devmode->bitsperpel = 0;
2126 nt_devmode->pelswidth = 0;
2127 nt_devmode->pelsheight = 0;
2128 nt_devmode->displayflags = 0;
2129 nt_devmode->displayfrequency = 0;
2130 nt_devmode->reserved1 = 0;
2131 nt_devmode->reserved2 = 0;
2132 nt_devmode->panningwidth = 0;
2133 nt_devmode->panningheight = 0;
2135 nt_devmode->private = NULL;
2139 /****************************************************************************
2140 Deepcopy an NT devicemode.
2141 ****************************************************************************/
2143 NT_DEVICEMODE *dup_nt_devicemode(NT_DEVICEMODE *nt_devicemode)
2145 NT_DEVICEMODE *new_nt_devicemode = NULL;
2147 if ((new_nt_devicemode = (NT_DEVICEMODE *)memdup(nt_devicemode, sizeof(NT_DEVICEMODE))) == NULL) {
2148 DEBUG(0,("dup_nt_devicemode: malloc fail.\n"));
2152 new_nt_devicemode->private = NULL;
2153 if (nt_devicemode->private != NULL) {
2154 if ((new_nt_devicemode->private = memdup(nt_devicemode->private, nt_devicemode->driverextra)) == NULL) {
2155 SAFE_FREE(new_nt_devicemode);
2156 DEBUG(0,("dup_nt_devicemode: malloc fail.\n"));
2161 return new_nt_devicemode;
2164 /****************************************************************************
2165 Clean up and deallocate a (maybe partially) allocated NT_DEVICEMODE.
2166 ****************************************************************************/
2168 void free_nt_devicemode(NT_DEVICEMODE **devmode_ptr)
2170 NT_DEVICEMODE *nt_devmode = *devmode_ptr;
2172 if(nt_devmode == NULL)
2175 DEBUG(106,("free_nt_devicemode: deleting DEVMODE\n"));
2177 SAFE_FREE(nt_devmode->private);
2178 SAFE_FREE(*devmode_ptr);
2181 /****************************************************************************
2182 Clean up and deallocate a (maybe partially) allocated NT_PRINTER_INFO_LEVEL_2.
2183 ****************************************************************************/
2184 static void free_nt_printer_info_level_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr)
2186 NT_PRINTER_INFO_LEVEL_2 *info = *info_ptr;
2187 NT_PRINTER_PARAM *param_ptr;
2192 DEBUG(106,("free_nt_printer_info_level_2: deleting info\n"));
2194 free_nt_devicemode(&info->devmode);
2196 for(param_ptr = info->specific; param_ptr; ) {
2197 NT_PRINTER_PARAM *tofree = param_ptr;
2199 param_ptr = param_ptr->next;
2200 free_nt_printer_param(&tofree);
2203 SAFE_FREE(*info_ptr);
2207 /****************************************************************************
2208 ****************************************************************************/
2209 static int unpack_devicemode(NT_DEVICEMODE **nt_devmode, char *buf, int buflen)
2213 NT_DEVICEMODE devmode;
2215 ZERO_STRUCT(devmode);
2217 len += tdb_unpack(buf+len, buflen-len, "p", nt_devmode);
2219 if (!*nt_devmode) return len;
2221 len += tdb_unpack(buf+len, buflen-len, "ffwwwwwwwwwwwwwwwwwwddddddddddddddp",
2225 &devmode.specversion,
2226 &devmode.driverversion,
2228 &devmode.driverextra,
2229 &devmode.orientation,
2231 &devmode.paperlength,
2232 &devmode.paperwidth,
2235 &devmode.defaultsource,
2236 &devmode.printquality,
2239 &devmode.yresolution,
2245 &devmode.bitsperpel,
2247 &devmode.pelsheight,
2248 &devmode.displayflags,
2249 &devmode.displayfrequency,
2253 &devmode.dithertype,
2256 &devmode.panningwidth,
2257 &devmode.panningheight,
2260 if (devmode.private) {
2261 /* the len in tdb_unpack is an int value and
2262 * devmode.driverextra is only a short
2264 len += tdb_unpack(buf+len, buflen-len, "B", &extra_len, &devmode.private);
2265 devmode.driverextra=(uint16)extra_len;
2267 /* check to catch an invalid TDB entry so we don't segfault */
2268 if (devmode.driverextra == 0) {
2269 devmode.private = NULL;
2273 *nt_devmode = (NT_DEVICEMODE *)memdup(&devmode, sizeof(devmode));
2275 DEBUG(8,("Unpacked devicemode [%s](%s)\n", devmode.devicename, devmode.formname));
2276 if (devmode.private)
2277 DEBUG(8,("with a private section of %d bytes\n", devmode.driverextra));
2282 /****************************************************************************
2283 ****************************************************************************/
2284 static int unpack_specifics(NT_PRINTER_PARAM **list, char *buf, int buflen)
2287 NT_PRINTER_PARAM param, *p;
2292 len += tdb_unpack(buf+len, buflen-len, "p", &p);
2295 len += tdb_unpack(buf+len, buflen-len, "fdB",
2301 *list = memdup(¶m, sizeof(param));
2303 DEBUG(8,("specific: [%s], len: %d\n", param.value, param.data_len));
2309 static void map_to_os2_driver(fstring drivername)
2311 static BOOL initialised=False;
2312 static fstring last_from,last_to;
2313 char *mapfile = lp_os2_driver_map();
2314 char **lines = NULL;
2318 if (!strlen(drivername))
2325 *last_from = *last_to = 0;
2329 if (strequal(drivername,last_from)) {
2330 DEBUG(3,("Mapped Windows driver %s to OS/2 driver %s\n",drivername,last_to));
2331 fstrcpy(drivername,last_to);
2335 lines = file_lines_load(mapfile, &numlines);
2336 if (numlines == 0) {
2337 DEBUG(0,("No entries in OS/2 driver map %s\n",mapfile));
2341 DEBUG(4,("Scanning OS/2 driver map %s\n",mapfile));
2343 for( i = 0; i < numlines; i++) {
2344 char *nt_name = lines[i];
2345 char *os2_name = strchr(nt_name,'=');
2352 while (isspace(*nt_name))
2355 if (!*nt_name || strchr("#;",*nt_name))
2359 int l = strlen(nt_name);
2360 while (l && isspace(nt_name[l-1])) {
2366 while (isspace(*os2_name))
2370 int l = strlen(os2_name);
2371 while (l && isspace(os2_name[l-1])) {
2377 if (strequal(nt_name,drivername)) {
2378 DEBUG(3,("Mapped windows driver %s to os2 driver%s\n",drivername,os2_name));
2379 fstrcpy(last_from,drivername);
2380 fstrcpy(last_to,os2_name);
2381 fstrcpy(drivername,os2_name);
2382 file_lines_free(lines);
2387 file_lines_free(lines);
2390 /****************************************************************************
2391 get a default printer info 2 struct
2392 ****************************************************************************/
2393 static WERROR get_a_printer_2_default(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstring sharename)
2396 NT_PRINTER_INFO_LEVEL_2 info;
2400 snum = lp_servicenumber(sharename);
2402 slprintf(info.servername, sizeof(info.servername)-1, "\\\\%s", get_called_name());
2403 slprintf(info.printername, sizeof(info.printername)-1, "\\\\%s\\%s",
2404 get_called_name(), sharename);
2405 fstrcpy(info.sharename, sharename);
2406 fstrcpy(info.portname, SAMBA_PRINTER_PORT_NAME);
2407 fstrcpy(info.drivername, lp_printerdriver(snum));
2409 /* by setting the driver name to an empty string, a local NT admin
2410 can now run the **local** APW to install a local printer driver
2411 for a Samba shared printer in 2.2. Without this, drivers **must** be
2412 installed on the Samba server for NT clients --jerry */
2413 #if 0 /* JERRY --do not uncomment-- */
2414 if (!*info.drivername)
2415 fstrcpy(info.drivername, "NO DRIVER AVAILABLE FOR THIS PRINTER");
2419 DEBUG(10,("get_a_printer_2_default: driver name set to [%s]\n", info.drivername));
2421 pstrcpy(info.comment, "");
2422 fstrcpy(info.printprocessor, "winprint");
2423 fstrcpy(info.datatype, "RAW");
2425 info.attributes = PRINTER_ATTRIBUTE_SHARED \
2426 | PRINTER_ATTRIBUTE_LOCAL \
2427 | PRINTER_ATTRIBUTE_RAW_ONLY \
2428 | PRINTER_ATTRIBUTE_QUEUED ; /* attributes */
2430 info.starttime = 0; /* Minutes since 12:00am GMT */
2431 info.untiltime = 0; /* Minutes since 12:00am GMT */
2433 info.default_priority = 1;
2434 info.setuptime = (uint32)time(NULL) - 86400; /* minus 1 day */
2437 * I changed this as I think it is better to have a generic
2438 * DEVMODE than to crash Win2k explorer.exe --jerry
2439 * See the HP Deskjet 990c Win2k drivers for an example.
2442 #if 0 /* JRA - NO NOT CHANGE ! */
2443 info.devmode = NULL;
2446 * We should not return a default devicemode, as this causes
2447 * Win2K to not send the correct one on PCL drivers. It needs to
2448 * see a null devicemode so it can then overwrite the devicemode
2449 * on OpenPrinterEx. Yes this *is* insane :-). JRA.
2451 if ((info.devmode = construct_nt_devicemode(info.printername)) == NULL)
2455 /* This will get the current RPC talloc context, but we should be
2456 passing this as a parameter... fixme... JRA ! */
2458 if (!nt_printing_getsec(get_talloc_ctx(), sharename, &info.secdesc_buf))
2461 *info_ptr = (NT_PRINTER_INFO_LEVEL_2 *)memdup(&info, sizeof(info));
2463 DEBUG(0,("get_a_printer_2_default: malloc fail.\n"));
2472 free_nt_devicemode(&info.devmode);
2473 return WERR_ACCESS_DENIED;
2476 /****************************************************************************
2477 ****************************************************************************/
2478 static WERROR get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstring sharename)
2481 NT_PRINTER_INFO_LEVEL_2 info;
2483 TDB_DATA kbuf, dbuf;
2484 fstring printername;
2488 slprintf(key, sizeof(key)-1, "%s%s", PRINTERS_PREFIX, sharename);
2491 kbuf.dsize = strlen(key)+1;
2493 dbuf = tdb_fetch(tdb_printers, kbuf);
2495 return get_a_printer_2_default(info_ptr, sharename);
2497 len += tdb_unpack(dbuf.dptr+len, dbuf.dsize-len, "dddddddddddfffffPfffff",
2500 &info.default_priority,
2517 info.printprocessor,
2521 /* Samba has to have shared raw drivers. */
2522 info.attributes |= (PRINTER_ATTRIBUTE_SHARED|PRINTER_ATTRIBUTE_RAW_ONLY);
2524 /* Restore the stripped strings. */
2525 slprintf(info.servername, sizeof(info.servername)-1, "\\\\%s", get_called_name());
2526 slprintf(printername, sizeof(printername)-1, "\\\\%s\\%s", get_called_name(),
2528 fstrcpy(info.printername, printername);
2530 len += unpack_devicemode(&info.devmode,dbuf.dptr+len, dbuf.dsize-len);
2533 * Some client drivers freak out if there is a NULL devmode
2534 * (probably the driver is not checking before accessing
2535 * the devmode pointer) --jerry
2539 DEBUG(8,("get_a_printer_2: Constructing a default device mode for [%s]\n",
2541 info.devmode = construct_nt_devicemode(printername);
2544 len += unpack_specifics(&info.specific,dbuf.dptr+len, dbuf.dsize-len);
2546 /* This will get the current RPC talloc context, but we should be
2547 passing this as a parameter... fixme... JRA ! */
2549 nt_printing_getsec(get_talloc_ctx(), sharename, &info.secdesc_buf);
2551 /* Fix for OS/2 drivers. */
2553 if (get_remote_arch() == RA_OS2)
2554 map_to_os2_driver(info.drivername);
2556 SAFE_FREE(dbuf.dptr);
2557 *info_ptr=memdup(&info, sizeof(info));
2559 DEBUG(9,("Unpacked printer [%s] name [%s] running driver [%s]\n",
2560 sharename, info.printername, info.drivername));
2565 /****************************************************************************
2566 debugging function, dump at level 6 the struct in the logs
2567 ****************************************************************************/
2568 static uint32 dump_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
2571 NT_PRINTER_INFO_LEVEL_2 *info2;
2573 DEBUG(106,("Dumping printer at level [%d]\n", level));
2579 if (printer.info_2 == NULL)
2583 info2=printer.info_2;
2585 DEBUGADD(106,("attributes:[%d]\n", info2->attributes));
2586 DEBUGADD(106,("priority:[%d]\n", info2->priority));
2587 DEBUGADD(106,("default_priority:[%d]\n", info2->default_priority));
2588 DEBUGADD(106,("starttime:[%d]\n", info2->starttime));
2589 DEBUGADD(106,("untiltime:[%d]\n", info2->untiltime));
2590 DEBUGADD(106,("status:[%d]\n", info2->status));
2591 DEBUGADD(106,("cjobs:[%d]\n", info2->cjobs));
2592 DEBUGADD(106,("averageppm:[%d]\n", info2->averageppm));
2593 DEBUGADD(106,("changeid:[%d]\n", info2->changeid));
2594 DEBUGADD(106,("c_setprinter:[%d]\n", info2->c_setprinter));
2595 DEBUGADD(106,("setuptime:[%d]\n", info2->setuptime));
2597 DEBUGADD(106,("servername:[%s]\n", info2->servername));
2598 DEBUGADD(106,("printername:[%s]\n", info2->printername));
2599 DEBUGADD(106,("sharename:[%s]\n", info2->sharename));
2600 DEBUGADD(106,("portname:[%s]\n", info2->portname));
2601 DEBUGADD(106,("drivername:[%s]\n", info2->drivername));
2602 DEBUGADD(106,("comment:[%s]\n", info2->comment));
2603 DEBUGADD(106,("location:[%s]\n", info2->location));
2604 DEBUGADD(106,("sepfile:[%s]\n", info2->sepfile));
2605 DEBUGADD(106,("printprocessor:[%s]\n", info2->printprocessor));
2606 DEBUGADD(106,("datatype:[%s]\n", info2->datatype));
2607 DEBUGADD(106,("parameters:[%s]\n", info2->parameters));
2613 DEBUGADD(1,("Level not implemented\n"));
2621 /****************************************************************************
2622 Get the parameters we can substitute in an NT print job.
2623 ****************************************************************************/
2625 void get_printer_subst_params(int snum, fstring *printername, fstring *sharename, fstring *portname)
2627 NT_PRINTER_INFO_LEVEL *printer = NULL;
2629 **printername = **sharename = **portname = '\0';
2631 if (!W_ERROR_IS_OK(get_a_printer(&printer, 2, lp_servicename(snum))))
2634 fstrcpy(*printername, printer->info_2->printername);
2635 fstrcpy(*sharename, printer->info_2->sharename);
2636 fstrcpy(*portname, printer->info_2->portname);
2638 free_a_printer(&printer, 2);
2641 /****************************************************************************
2642 Update the changeid time.
2643 This is SO NASTY as some drivers need this to change, others need it
2644 static. This value will change every second, and I must hope that this
2645 is enough..... DON'T CHANGE THIS CODE WITHOUT A TEST MATRIX THE SIZE OF
2647 ****************************************************************************/
2649 static uint32 rev_changeid(void)
2651 static time_t start_time;
2652 if (start_time == 0)
2653 start_time = time(NULL);
2654 return (((time(NULL) - start_time)+1)*1000);
2658 * The function below are the high level ones.
2659 * only those ones must be called from the spoolss code.
2663 /****************************************************************************
2664 Modify a printer. This is called from SETPRINTERDATA/DELETEPRINTERDATA.
2665 ****************************************************************************/
2667 WERROR mod_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
2671 dump_a_printer(printer, level);
2678 * Update the changestamp. Emperical tests show that the
2679 * ChangeID is always updated,but c_setprinter is only
2680 * incremented on a SetPrinter() call.
2683 /* ChangeID **must** be increasing over the lifetime
2684 of client's spoolss service in order for the
2685 client's cache to show updates */
2687 printer.info_2->changeid = rev_changeid();
2690 * Because one day someone will ask:
2691 * NT->NT An admin connection to a remote
2692 * printer show changes imeediately in
2693 * the properities dialog
2695 * A non-admin connection will only show the
2696 * changes after viewing the properites page
2697 * 2 times. Seems to be related to a
2698 * race condition in the client between the spooler
2699 * updating the local cache and the Explorer.exe GUI
2700 * actually displaying the properties.
2702 * This is fixed in Win2k. admin/non-admin
2703 * connections both display changes immediately.
2708 result=update_a_printer_2(printer.info_2);
2712 result=WERR_UNKNOWN_LEVEL;
2719 /****************************************************************************
2720 Add a printer. This is called from ADDPRINTER(EX) and also SETPRINTER.
2721 We split this out from mod_a_printer as it updates the id's and timestamps.
2722 ****************************************************************************/
2724 WERROR add_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
2728 dump_a_printer(printer, level);
2735 * Update the changestamp. See comments in mod_a_printer()
2739 printer.info_2->changeid = rev_changeid();
2740 printer.info_2->c_setprinter++;
2742 result=update_a_printer_2(printer.info_2);
2746 result=WERR_UNKNOWN_LEVEL;
2753 /****************************************************************************
2754 Initialize printer devmode & data with previously saved driver init values.
2755 ****************************************************************************/
2756 static uint32 set_driver_init_2(NT_PRINTER_INFO_LEVEL_2 *info_ptr)
2760 TDB_DATA kbuf, dbuf;
2761 NT_PRINTER_PARAM *current;
2762 NT_PRINTER_INFO_LEVEL_2 info;
2766 slprintf(key, sizeof(key)-1, "%s%s", DRIVER_INIT_PREFIX, info_ptr->drivername);
2769 kbuf.dsize = strlen(key)+1;
2771 dbuf = tdb_fetch(tdb_drivers, kbuf);
2776 * Get the saved DEVMODE..
2778 len += unpack_devicemode(&info.devmode,dbuf.dptr+len, dbuf.dsize-len);
2781 * The saved DEVMODE contains the devicename from the printer used during
2782 * the initialization save. Change it to reflect the new printer.
2784 ZERO_STRUCT(info.devmode->devicename);
2785 fstrcpy(info.devmode->devicename, info_ptr->printername);
2788 * Bind the saved DEVMODE to the new the printer.
2790 free_nt_devicemode(&info_ptr->devmode);
2791 info_ptr->devmode = info.devmode;
2793 DEBUG(10,("set_driver_init_2: Set printer [%s] init DEVMODE for driver [%s]\n",
2794 info_ptr->printername, info_ptr->drivername));
2797 * There should not be any printer data 'specifics' already set during the
2798 * add printer operation, if there are delete them.
2800 while ( (current=info_ptr->specific) != NULL ) {
2801 info_ptr->specific=current->next;
2802 SAFE_FREE(current->data);
2807 * Add the printer data 'specifics' to the new printer
2809 len += unpack_specifics(&info_ptr->specific,dbuf.dptr+len, dbuf.dsize-len);
2811 SAFE_FREE(dbuf.dptr);
2816 /****************************************************************************
2817 Initialize printer devmode & data with previously saved driver init values.
2818 When a printer is created using AddPrinter, the drivername bound to the
2819 printer is used to lookup previously saved driver initialization info, which
2820 is bound to the new printer.
2821 ****************************************************************************/
2823 uint32 set_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level)
2831 result=set_driver_init_2(printer->info_2);
2842 /****************************************************************************
2843 Pack up the DEVMODE and specifics for a printer into a 'driver init' entry
2844 in the tdb. Note: this is different from the driver entry and the printer
2845 entry. There should be a single driver init entry for each driver regardless
2846 of whether it was installed from NT or 2K. Technically, they should be
2847 different, but they work out to the same struct.
2848 ****************************************************************************/
2849 static uint32 update_driver_init_2(NT_PRINTER_INFO_LEVEL_2 *info)
2853 int buflen, len, ret;
2854 TDB_DATA kbuf, dbuf;
2861 len += pack_devicemode(info->devmode, buf+len, buflen-len);
2863 len += pack_specifics(info->specific, buf+len, buflen-len);
2865 if (buflen != len) {
2868 tb = (char *)Realloc(buf, len);
2870 DEBUG(0, ("update_driver_init_2: failed to enlarge buffer!\n"));
2879 slprintf(key, sizeof(key)-1, "%s%s", DRIVER_INIT_PREFIX, info->drivername);
2882 kbuf.dsize = strlen(key)+1;
2886 ret = tdb_store(tdb_drivers, kbuf, dbuf, TDB_REPLACE);
2890 DEBUG(8, ("update_driver_init_2: error updating printer init to tdb on disk\n"));
2894 DEBUG(10,("update_driver_init_2: Saved printer [%s] init DEVMODE & specifics for driver [%s]\n",
2895 info->sharename, info->drivername));
2900 /****************************************************************************
2901 Update (i.e. save) the driver init info (DEVMODE and specifics) for a printer
2902 ****************************************************************************/
2904 static uint32 update_driver_init(NT_PRINTER_INFO_LEVEL printer, uint32 level)
2908 dump_a_printer(printer, level);
2914 result=update_driver_init_2(printer.info_2);
2925 /****************************************************************************
2926 Convert the printer data value, a REG_BINARY array, into an initialization
2927 DEVMODE. Note: the array must be parsed as if it was a DEVMODE in an rpc...
2928 got to keep the endians happy :).
2929 ****************************************************************************/
2931 static BOOL convert_driver_init(NT_PRINTER_PARAM *param, TALLOC_CTX *ctx, NT_DEVICEMODE *nt_devmode)
2933 BOOL result = False;
2937 ZERO_STRUCT(devmode);
2939 prs_init(&ps, 0, ctx, UNMARSHALL);
2940 ps.data_p = (char *)param->data;
2941 ps.buffer_size = param->data_len;
2943 if (spoolss_io_devmode("phantom DEVMODE", &ps, 0, &devmode))
2944 result = convert_devicemode("", &devmode, &nt_devmode);
2946 DEBUG(10,("convert_driver_init: error parsing DEVMODE\n"));
2951 /****************************************************************************
2952 Set the DRIVER_INIT info in the tdb. Requires Win32 client code that:
2954 1. Use the driver's config DLL to this UNC printername and:
2955 a. Call DrvPrintEvent with PRINTER_EVENT_INITIALIZE
2956 b. Call DrvConvertDevMode with CDM_DRIVER_DEFAULT to get default DEVMODE
2957 2. Call SetPrinterData with the 'magic' key and the DEVMODE as data.
2959 The last step triggers saving the "driver initialization" information for
2960 this printer into the tdb. Later, new printers that use this driver will
2961 have this initialization information bound to them. This simulates the
2962 driver initialization, as if it had run on the Samba server (as it would
2965 The Win32 client side code requirement sucks! But until we can run arbitrary
2966 Win32 printer driver code on any Unix that Samba runs on, we are stuck with it.
2968 It would have been easier to use SetPrinter because all the UNMARSHALLING of
2969 the DEVMODE is done there, but 2K/XP clients do not set the DEVMODE... think
2970 about it and you will realize why. JRR 010720
2971 ****************************************************************************/
2973 static WERROR save_driver_init_2(NT_PRINTER_INFO_LEVEL *printer, NT_PRINTER_PARAM *param)
2975 WERROR status = WERR_OK;
2976 TALLOC_CTX *ctx = NULL;
2977 NT_DEVICEMODE *nt_devmode = NULL;
2978 NT_DEVICEMODE *tmp_devmode = printer->info_2->devmode;
2981 * Set devmode on printer info, so entire printer initialization can be
2984 if ((ctx = talloc_init()) == NULL)
2987 if ((nt_devmode = (NT_DEVICEMODE*)malloc(sizeof(NT_DEVICEMODE))) == NULL) {
2988 status = WERR_NOMEM;
2992 ZERO_STRUCTP(nt_devmode);
2995 * The DEVMODE is held in the 'data' component of the param in raw binary.
2996 * Convert it to to a devmode structure
2998 if (!convert_driver_init(param, ctx, nt_devmode)) {
2999 DEBUG(10,("save_driver_init_2: error converting DEVMODE\n"));
3000 status = WERR_INVALID_PARAM;
3005 * Pack up and add (or update) the DEVMODE and any current printer data to
3006 * a 'driver init' element in the tdb
3009 printer->info_2->devmode = nt_devmode;
3010 if (update_driver_init(*printer, 2)!=0) {
3011 DEBUG(10,("save_driver_init_2: error updating DEVMODE\n"));
3012 status = WERR_NOMEM;
3017 * If driver initialization info was successfully saved, set the current
3018 * printer to match it. This allows initialization of the current printer
3019 * as well as the driver.
3021 status = mod_a_printer(*printer, 2);
3022 if (!W_ERROR_IS_OK(status)) {
3023 DEBUG(10,("save_driver_init_2: error setting DEVMODE on printer [%s]\n",
3024 printer->info_2->printername));
3028 talloc_destroy(ctx);
3030 SAFE_FREE(nt_devmode->private);
3031 SAFE_FREE(nt_devmode);
3032 printer->info_2->devmode = tmp_devmode;
3037 /****************************************************************************
3038 Update the driver init info (DEVMODE and specifics) for a printer
3039 ****************************************************************************/
3041 WERROR save_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level, NT_PRINTER_PARAM *param)
3043 WERROR status = WERR_OK;
3049 status=save_driver_init_2(printer, param);
3053 status=WERR_UNKNOWN_LEVEL;
3060 /****************************************************************************
3061 Get a NT_PRINTER_INFO_LEVEL struct. It returns malloced memory.
3062 ****************************************************************************/
3064 WERROR get_a_printer(NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level, fstring sharename)
3067 NT_PRINTER_INFO_LEVEL *printer = NULL;
3071 DEBUG(10,("get_a_printer: [%s] level %u\n", sharename, (unsigned int)level));
3077 if ((printer = (NT_PRINTER_INFO_LEVEL *)malloc(sizeof(NT_PRINTER_INFO_LEVEL))) == NULL) {
3078 DEBUG(0,("get_a_printer: malloc fail.\n"));
3081 ZERO_STRUCTP(printer);
3082 result=get_a_printer_2(&printer->info_2, sharename);
3083 if (W_ERROR_IS_OK(result)) {
3084 dump_a_printer(*printer, level);
3085 *pp_printer = printer;
3092 result=WERR_UNKNOWN_LEVEL;
3096 DEBUG(10,("get_a_printer: [%s] level %u returning %s\n", sharename, (unsigned int)level, werror_str(result)));
3101 /****************************************************************************
3102 Deletes a NT_PRINTER_INFO_LEVEL struct.
3103 ****************************************************************************/
3105 uint32 free_a_printer(NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level)
3108 NT_PRINTER_INFO_LEVEL *printer = *pp_printer;
3110 DEBUG(104,("freeing a printer at level [%d]\n", level));
3112 if (printer == NULL)
3119 if (printer->info_2 != NULL)
3121 free_nt_printer_info_level_2(&printer->info_2);
3135 SAFE_FREE(*pp_printer);
3139 /****************************************************************************
3140 ****************************************************************************/
3141 uint32 add_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
3144 DEBUG(104,("adding a printer at level [%d]\n", level));
3145 dump_a_printer_driver(driver, level);
3151 result=add_a_printer_driver_3(driver.info_3);
3157 result=add_a_printer_driver_6(driver.info_6);
3167 /****************************************************************************
3168 ****************************************************************************/
3169 WERROR get_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL *driver, uint32 level,
3170 fstring printername, fstring architecture, uint32 version)
3178 result=get_a_printer_driver_3(&driver->info_3, printername, architecture, version);
3186 if (W_ERROR_IS_OK(result))
3187 dump_a_printer_driver(*driver, level);
3191 /****************************************************************************
3192 ****************************************************************************/
3193 uint32 free_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
3201 NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3;
3202 if (driver.info_3 != NULL)
3204 info3=driver.info_3;
3205 SAFE_FREE(info3->dependentfiles);
3206 ZERO_STRUCTP(info3);
3218 NT_PRINTER_DRIVER_INFO_LEVEL_6 *info6;
3219 if (driver.info_6 != NULL)
3221 info6=driver.info_6;
3222 SAFE_FREE(info6->dependentfiles);
3223 SAFE_FREE(info6->previousnames);
3224 ZERO_STRUCTP(info6);
3242 /****************************************************************************
3243 Determine whether or not a particular driver is currently assigned
3245 ****************************************************************************/
3246 BOOL printer_driver_in_use (char *arch, char *driver)
3248 TDB_DATA kbuf, newkey, dbuf;
3249 NT_PRINTER_INFO_LEVEL_2 info;
3253 if (!nt_printing_init())
3256 DEBUG(5,("printer_driver_in_use: Beginning search through printers.tdb...\n"));
3258 /* loop through the printers.tdb and check for the drivername */
3259 for (kbuf = tdb_firstkey(tdb_printers); kbuf.dptr;
3260 newkey = tdb_nextkey(tdb_printers, kbuf), safe_free(kbuf.dptr), kbuf=newkey)
3263 dbuf = tdb_fetch(tdb_printers, kbuf);
3267 if (strncmp(kbuf.dptr, PRINTERS_PREFIX, strlen(PRINTERS_PREFIX)) != 0)
3270 ret = tdb_unpack(dbuf.dptr, dbuf.dsize, "dddddddddddfffffPfffff",
3273 &info.default_priority,
3290 info.printprocessor,
3294 SAFE_FREE(dbuf.dptr);
3297 DEBUG (0,("printer_driver_in_use: tdb_unpack failed for printer %s\n",
3302 DEBUG (10,("printer_driver_in_use: Printer - %s (%s)\n",
3303 info.printername, info.drivername));
3305 if (strcmp(info.drivername, driver) == 0)
3307 DEBUG(5,("printer_driver_in_use: Printer %s using %s\n",
3308 info.printername, driver));
3312 DEBUG(5,("printer_driver_in_use: Completed search through printers.tdb...\n"));
3316 /* report that the driver is in use by default */
3320 /****************************************************************************
3321 Remove a printer driver from the TDB. This assumes that the the driver was
3322 previously looked up.
3323 ***************************************************************************/
3324 WERROR delete_printer_driver (NT_PRINTER_DRIVER_INFO_LEVEL_3 *i)
3331 get_short_archi(arch, i->environment);
3332 slprintf(key, sizeof(key)-1, "%s%s/%d/%s", DRIVERS_PREFIX,
3333 arch, i->cversion, i->name);
3334 DEBUG(5,("delete_printer_driver: key = [%s]\n", key));
3337 kbuf.dsize=strlen(key)+1;
3339 if (tdb_delete(tdb_drivers, kbuf) == -1) {
3340 DEBUG (0,("delete_printer_driver: fail to delete %s!\n", key));
3341 return WERR_ACCESS_DENIED;
3344 DEBUG(5,("delete_printer_driver: [%s] driver delete successful.\n",
3349 /****************************************************************************
3350 ****************************************************************************/
3351 BOOL get_specific_param_by_index(NT_PRINTER_INFO_LEVEL printer, uint32 level, uint32 param_index,
3352 fstring value, uint8 **data, uint32 *type, uint32 *len)
3354 /* right now that's enough ! */
3355 NT_PRINTER_PARAM *param;
3358 param=printer.info_2->specific;
3360 while (param != NULL && i < param_index) {
3368 /* exited because it exist */
3370 StrnCpy(value, param->value, sizeof(fstring)-1);
3371 *data=(uint8 *)malloc(param->data_len*sizeof(uint8));
3374 ZERO_STRUCTP(*data);
3375 memcpy(*data, param->data, param->data_len);
3376 *len=param->data_len;
3380 /****************************************************************************
3381 ****************************************************************************/
3382 BOOL get_specific_param(NT_PRINTER_INFO_LEVEL printer, uint32 level,
3383 fstring value, uint8 **data, uint32 *type, uint32 *len)
3385 /* right now that's enough ! */
3386 NT_PRINTER_PARAM *param;
3388 DEBUG(10, ("get_specific_param\n"));
3390 param=printer.info_2->specific;
3392 while (param != NULL)
3394 #if 1 /* JRA - I think this should be case insensitive.... */
3395 if ( strequal(value, param->value)
3397 if ( !strcmp(value, param->value)
3399 && strlen(value)==strlen(param->value))
3407 DEBUGADD(10, ("get_specific_param: found one param\n"));
3408 /* exited because it exist */
3411 *data=(uint8 *)malloc(param->data_len*sizeof(uint8));
3414 memcpy(*data, param->data, param->data_len);
3415 *len=param->data_len;
3417 DEBUGADD(10, ("get_specific_param: exit true\n"));
3420 DEBUGADD(10, ("get_specific_param: exit false\n"));
3424 /****************************************************************************
3425 Store a security desc for a printer.
3426 ****************************************************************************/
3428 WERROR nt_printing_setsec(char *printername, SEC_DESC_BUF *secdesc_ctr)
3430 SEC_DESC_BUF *new_secdesc_ctr = NULL;
3431 SEC_DESC_BUF *old_secdesc_ctr = NULL;
3433 TALLOC_CTX *mem_ctx = NULL;
3437 mem_ctx = talloc_init();
3438 if (mem_ctx == NULL)
3441 /* The old owner and group sids of the security descriptor are not
3442 present when new ACEs are added or removed by changing printer
3443 permissions through NT. If they are NULL in the new security
3444 descriptor then copy them over from the old one. */
3446 if (!secdesc_ctr->sec->owner_sid || !secdesc_ctr->sec->grp_sid) {
3447 DOM_SID *owner_sid, *group_sid;
3448 SEC_ACL *dacl, *sacl;
3449 SEC_DESC *psd = NULL;
3452 nt_printing_getsec(mem_ctx, printername, &old_secdesc_ctr);
3454 /* Pick out correct owner and group sids */
3456 owner_sid = secdesc_ctr->sec->owner_sid ?
3457 secdesc_ctr->sec->owner_sid :
3458 old_secdesc_ctr->sec->owner_sid;
3460 group_sid = secdesc_ctr->sec->grp_sid ?
3461 secdesc_ctr->sec->grp_sid :
3462 old_secdesc_ctr->sec->grp_sid;
3464 dacl = secdesc_ctr->sec->dacl ?
3465 secdesc_ctr->sec->dacl :
3466 old_secdesc_ctr->sec->dacl;
3468 sacl = secdesc_ctr->sec->sacl ?
3469 secdesc_ctr->sec->sacl :
3470 old_secdesc_ctr->sec->sacl;
3472 /* Make a deep copy of the security descriptor */
3474 psd = make_sec_desc(mem_ctx, secdesc_ctr->sec->revision,
3475 owner_sid, group_sid,
3480 new_secdesc_ctr = make_sec_desc_buf(mem_ctx, size, psd);
3483 if (!new_secdesc_ctr) {
3484 new_secdesc_ctr = secdesc_ctr;
3487 /* Store the security descriptor in a tdb */
3489 prs_init(&ps, (uint32)sec_desc_size(new_secdesc_ctr->sec) +
3490 sizeof(SEC_DESC_BUF), mem_ctx, MARSHALL);
3492 if (!sec_io_desc_buf("nt_printing_setsec", &new_secdesc_ctr,
3494 status = WERR_BADFUNC;
3498 slprintf(key, sizeof(key)-1, "SECDESC/%s", printername);
3500 if (tdb_prs_store(tdb_printers, key, &ps)==0) {
3503 DEBUG(1,("Failed to store secdesc for %s\n", printername));
3504 status = WERR_BADFUNC;
3507 /* Free malloc'ed memory */
3513 talloc_destroy(mem_ctx);
3517 /****************************************************************************
3518 Construct a default security descriptor buffer for a printer.
3519 ****************************************************************************/
3521 static SEC_DESC_BUF *construct_default_printer_sdb(TALLOC_CTX *ctx)
3525 SEC_ACL *psa = NULL;
3526 SEC_DESC_BUF *sdb = NULL;
3527 SEC_DESC *psd = NULL;
3530 enum SID_NAME_USE name_type;
3532 /* Create an ACE where Everyone is allowed to print */
3534 init_sec_access(&sa, PRINTER_ACE_PRINT);
3535 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
3536 sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
3538 /* Make the security descriptor owned by the Administrators group
3539 on the PDC of the domain. */
3541 if (winbind_lookup_name(lp_workgroup(), &owner_sid, &name_type)) {
3542 sid_append_rid(&owner_sid, DOMAIN_USER_RID_ADMIN);
3546 /* Backup plan - make printer owned by admins or root.
3547 This should emulate a lanman printer as security
3548 settings can't be changed. */
3550 sid_peek_rid(&owner_sid, &owner_rid);
3552 if (owner_rid != BUILTIN_ALIAS_RID_PRINT_OPS &&
3553 owner_rid != BUILTIN_ALIAS_RID_ADMINS &&
3554 owner_rid != DOMAIN_USER_RID_ADMIN &&
3555 !lookup_name("root", &owner_sid, &name_type)) {
3556 sid_copy(&owner_sid, &global_sid_World);
3560 init_sec_access(&sa, PRINTER_ACE_FULL_CONTROL);
3561 init_sec_ace(&ace[1], &owner_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
3562 sa, SEC_ACE_FLAG_OBJECT_INHERIT |
3563 SEC_ACE_FLAG_INHERIT_ONLY);
3565 init_sec_access(&sa, PRINTER_ACE_FULL_CONTROL);
3566 init_sec_ace(&ace[2], &owner_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
3567 sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
3569 /* The ACL revision number in rpc_secdesc.h differs from the one
3570 created by NT when setting ACE entries in printer
3571 descriptors. NT4 complains about the property being edited by a
3574 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) != NULL) {
3575 psd = make_sec_desc(ctx, SEC_DESC_REVISION,
3577 NULL, psa, &sd_size);
3581 DEBUG(0,("construct_default_printer_sdb: Failed to make SEC_DESC.\n"));
3585 sdb = make_sec_desc_buf(ctx, sd_size, psd);
3587 DEBUG(4,("construct_default_printer_sdb: size = %u.\n",
3588 (unsigned int)sd_size));
3593 /****************************************************************************
3594 Get a security desc for a printer.
3595 ****************************************************************************/
3597 BOOL nt_printing_getsec(TALLOC_CTX *ctx, char *printername, SEC_DESC_BUF **secdesc_ctr)
3603 if ((temp = strchr(printername + 2, '\\'))) {
3604 printername = temp + 1;
3607 /* Fetch security descriptor from tdb */
3609 slprintf(key, sizeof(key)-1, "SECDESC/%s", printername);
3611 if (tdb_prs_fetch(tdb_printers, key, &ps, ctx)!=0 ||
3612 !sec_io_desc_buf("nt_printing_getsec", secdesc_ctr, &ps, 1)) {
3614 DEBUG(4,("using default secdesc for %s\n", printername));
3616 if (!(*secdesc_ctr = construct_default_printer_sdb(ctx))) {
3620 /* Save default security descriptor for later */
3622 prs_init(&ps, (uint32)sec_desc_size((*secdesc_ctr)->sec) +
3623 sizeof(SEC_DESC_BUF), ctx, MARSHALL);
3625 if (sec_io_desc_buf("nt_printing_setsec", secdesc_ctr, &ps, 1))
3626 tdb_prs_store(tdb_printers, key, &ps);
3633 /* If security descriptor is owned by S-1-1-0 and winbindd is up,
3634 this security descriptor has been created when winbindd was
3635 down. Take ownership of security descriptor. */
3637 if (sid_equal((*secdesc_ctr)->sec->owner_sid, &global_sid_World)) {
3639 enum SID_NAME_USE name_type;
3641 /* Change sd owner to workgroup administrator */
3643 if (winbind_lookup_name(lp_workgroup(), &owner_sid,
3645 SEC_DESC_BUF *new_secdesc_ctr = NULL;
3646 SEC_DESC *psd = NULL;
3651 sid_append_rid(&owner_sid, DOMAIN_USER_RID_ADMIN);
3653 psd = make_sec_desc(ctx, (*secdesc_ctr)->sec->revision,
3655 (*secdesc_ctr)->sec->grp_sid,
3656 (*secdesc_ctr)->sec->sacl,
3657 (*secdesc_ctr)->sec->dacl,
3660 new_secdesc_ctr = make_sec_desc_buf(ctx, size, psd);
3662 /* Swap with other one */
3664 *secdesc_ctr = new_secdesc_ctr;
3668 nt_printing_setsec(printername, *secdesc_ctr);
3672 if (DEBUGLEVEL >= 10) {
3673 SEC_ACL *the_acl = (*secdesc_ctr)->sec->dacl;
3676 DEBUG(10, ("secdesc_ctr for %s has %d aces:\n",
3677 printername, the_acl->num_aces));
3679 for (i = 0; i < the_acl->num_aces; i++) {
3682 sid_to_string(sid_str, &the_acl->ace[i].trustee);
3684 DEBUG(10, ("%s %d %d 0x%08x\n", sid_str,
3685 the_acl->ace[i].type, the_acl->ace[i].flags,
3686 the_acl->ace[i].info.mask));
3696 1: level not implemented
3697 2: file doesn't exist
3698 3: can't allocate memory
3699 4: can't free memory
3700 5: non existant struct
3704 A printer and a printer driver are 2 different things.
3705 NT manages them separatelly, Samba does the same.
3706 Why ? Simply because it's easier and it makes sense !
3708 Now explanation: You have 3 printers behind your samba server,
3709 2 of them are the same make and model (laser A and B). But laser B
3710 has an 3000 sheet feeder and laser A doesn't such an option.
3711 Your third printer is an old dot-matrix model for the accounting :-).
3713 If the /usr/local/samba/lib directory (default dir), you will have
3714 5 files to describe all of this.
3716 3 files for the printers (1 by printer):
3719 NTprinter_accounting
3720 2 files for the drivers (1 for the laser and 1 for the dot matrix)
3721 NTdriver_printer model X
3722 NTdriver_printer model Y
3724 jfm: I should use this comment for the text file to explain
3725 same thing for the forms BTW.
3726 Je devrais mettre mes commentaires en francais, ca serait mieux :-)
3730 /* Convert generic access rights to printer object specific access rights.
3731 It turns out that NT4 security descriptors use generic access rights and
3732 NT5 the object specific ones. */
3734 void map_printer_permissions(SEC_DESC *sd)
3738 for (i = 0; sd->dacl && i < sd->dacl->num_aces; i++) {
3739 se_map_generic(&sd->dacl->ace[i].info.mask,
3740 &printer_generic_mapping);
3744 /****************************************************************************
3745 Check a user has permissions to perform the given operation. We use the
3746 permission constants defined in include/rpc_spoolss.h to check the various
3747 actions we perform when checking printer access.
3749 PRINTER_ACCESS_ADMINISTER:
3750 print_queue_pause, print_queue_resume, update_printer_sec,
3751 update_printer, spoolss_addprinterex_level_2,
3752 _spoolss_setprinterdata
3757 JOB_ACCESS_ADMINISTER:
3758 print_job_delete, print_job_pause, print_job_resume,
3761 ****************************************************************************/
3762 BOOL print_access_check(struct current_user *user, int snum, int access_type)
3764 SEC_DESC_BUF *secdesc = NULL;
3765 uint32 access_granted;
3769 TALLOC_CTX *mem_ctx = NULL;
3770 extern struct current_user current_user;
3772 /* If user is NULL then use the current_user structure */
3775 user = ¤t_user;
3777 /* Always allow root or printer admins to do anything */
3779 if (user->uid == 0 ||
3780 user_in_list(uidtoname(user->uid), lp_printer_admin(snum))) {
3784 /* Get printer name */
3786 pname = PRINTERNAME(snum);
3788 if (!pname || !*pname) {
3793 /* Get printer security descriptor */
3795 if(!(mem_ctx = talloc_init())) {
3800 nt_printing_getsec(mem_ctx, pname, &secdesc);
3802 if (access_type == JOB_ACCESS_ADMINISTER) {
3803 SEC_DESC_BUF *parent_secdesc = secdesc;
3805 /* Create a child security descriptor to check permissions
3806 against. This is because print jobs are child objects
3807 objects of a printer. */
3809 secdesc = se_create_child_secdesc(mem_ctx, parent_secdesc->sec, False);
3811 /* Now this is the bit that really confuses me. The access
3812 type needs to be changed from JOB_ACCESS_ADMINISTER to
3813 PRINTER_ACCESS_ADMINISTER for this to work. Something
3814 to do with the child (job) object becoming like a
3817 access_type = PRINTER_ACCESS_ADMINISTER;
3822 map_printer_permissions(secdesc->sec);
3824 result = se_access_check(secdesc->sec, user->nt_user_token, access_type,
3825 &access_granted, &status);
3827 DEBUG(4, ("access check was %s\n", result ? "SUCCESS" : "FAILURE"));
3829 talloc_destroy(mem_ctx);
3837 /****************************************************************************
3838 Check the time parameters allow a print operation.
3839 *****************************************************************************/
3841 BOOL print_time_access_check(int snum)
3843 NT_PRINTER_INFO_LEVEL *printer = NULL;
3845 time_t now = time(NULL);
3849 if (!W_ERROR_IS_OK(get_a_printer(&printer, 2, lp_servicename(snum))))
3852 if (printer->info_2->starttime == 0 && printer->info_2->untiltime == 0)
3856 mins = (uint32)t->tm_hour*60 + (uint32)t->tm_min;
3858 if (mins >= printer->info_2->starttime && mins <= printer->info_2->untiltime)
3861 free_a_printer(&printer, 2);
3869 /****************************************************************************
3870 Attempt to write a default device.
3871 *****************************************************************************/
3873 WERROR printer_write_default_dev(int snum, const PRINTER_DEFAULT *printer_default)
3875 NT_PRINTER_INFO_LEVEL *printer = NULL;
3879 * Don't bother if no default devicemode was sent.
3882 if (printer_default->devmode_cont.devmode == NULL)
3885 result = get_a_printer(&printer, 2, lp_servicename(snum));
3886 if (!W_ERROR_IS_OK(result)) return result;
3889 * Just ignore it if we already have a devmode.
3892 if (printer->info_2->devmode != NULL)
3896 * We don't have a devicemode and we're trying to write
3897 * one. Check we have the access needed.
3899 DEBUG(5,("printer_write_default_dev: access: %x\n", printer_default->access_required));
3901 if ( (printer_default->access_required & PRINTER_ACCESS_ADMINISTER) !=
3902 PRINTER_ACCESS_ADMINISTER) {
3903 DEBUG(5,("printer_write_default_dev: invalid request access to update: %x\n", printer_default->access_required));
3904 result = WERR_ACCESS_DENIED;
3908 if (!print_access_check(NULL, snum, PRINTER_ACCESS_ADMINISTER)) {
3909 DEBUG(5,("printer_write_default_dev: Access denied for printer %s\n",
3910 lp_servicename(snum) ));
3911 result = WERR_ACCESS_DENIED;
3912 /*result = NT_STATUS_NO_PROBLEMO;*/
3916 DEBUG(5,("printer_write_default_dev: updating, check OK.\n"));
3919 * Convert the on the wire devicemode format to the internal one.
3922 if (!convert_devicemode(printer->info_2->printername,
3923 printer_default->devmode_cont.devmode,
3924 &printer->info_2->devmode)) {
3925 result = WERR_NOMEM;
3930 * Finally write back to the tdb.
3933 result = add_a_printer(*printer, 2);
3937 free_a_printer(&printer, 2);