printing: Fix a DBG message
[samba.git] / source3 / printing / nt_printing_tdb.c
1 /*
2  *  Unix SMB/CIFS implementation.
3  *  RPC Pipe client / server routines
4  *  Copyright (c) Andrew Tridgell              1992-2000,
5  *  Copyright (c) Jean François Micouleau      1998-2000.
6  *  Copyright (c) Gerald Carter                2002-2005.
7  *  Copyright (c) Andreas Schneider            2010.
8  *
9  *  This program is free software; you can redistribute it and/or modify
10  *  it under the terms of the GNU General Public License as published by
11  *  the Free Software Foundation; either version 3 of the License, or
12  *  (at your option) any later version.
13  *
14  *  This program is distributed in the hope that it will be useful,
15  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  *  GNU General Public License for more details.
18  *
19  *  You should have received a copy of the GNU General Public License
20  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
21  */
22
23 #include "includes.h"
24 #include "system/filesys.h"
25 #include "printing/nt_printing_tdb.h"
26 #include "librpc/gen_ndr/spoolss.h"
27 #include "librpc/gen_ndr/ndr_security.h"
28 #include "libcli/security/security.h"
29 #include "util_tdb.h"
30 #include "lib/util/string_wrappers.h"
31
32 #define FORMS_PREFIX "FORMS/"
33 #define DRIVERS_PREFIX "DRIVERS/"
34 #define PRINTERS_PREFIX "PRINTERS/"
35 #define SECDESC_PREFIX "SECDESC/"
36
37 #define NTDRIVERS_DATABASE_VERSION_1 1
38 #define NTDRIVERS_DATABASE_VERSION_2 2
39 #define NTDRIVERS_DATABASE_VERSION_3 3 /* little endian version of v2 */
40 #define NTDRIVERS_DATABASE_VERSION_4 4 /* fix generic bits in security descriptors */
41 #define NTDRIVERS_DATABASE_VERSION_5 5 /* normalize keys in ntprinters.tdb */
42
43 static TDB_CONTEXT *tdb_forms; /* used for forms files */
44 static TDB_CONTEXT *tdb_drivers; /* used for driver files */
45 static TDB_CONTEXT *tdb_printers; /* used for printers files */
46
47 /****************************************************************************
48  generate a new TDB_DATA key for storing a printer
49 ****************************************************************************/
50
51 static TDB_DATA make_printer_tdbkey(TALLOC_CTX *ctx, const char *sharename )
52 {
53         fstring share;
54         char *keystr = NULL;
55         TDB_DATA key;
56
57         fstrcpy(share, sharename);
58         (void)strlower_m(share);
59
60         keystr = talloc_asprintf(ctx, "%s%s", PRINTERS_PREFIX, share);
61         key = string_term_tdb_data(keystr ? keystr : "");
62
63         return key;
64 }
65
66 /****************************************************************************
67  generate a new TDB_DATA key for storing a printer security descriptor
68 ****************************************************************************/
69
70 static TDB_DATA make_printers_secdesc_tdbkey(TALLOC_CTX *ctx,
71                                         const char* sharename  )
72 {
73         fstring share;
74         char *keystr = NULL;
75         TDB_DATA key;
76
77         fstrcpy(share, sharename );
78         (void)strlower_m(share);
79
80         keystr = talloc_asprintf(ctx, "%s%s", SECDESC_PREFIX, share);
81         key = string_term_tdb_data(keystr ? keystr : "");
82
83         return key;
84 }
85
86 /****************************************************************************
87  Upgrade the tdb files to version 3
88 ****************************************************************************/
89
90 static bool upgrade_to_version_3(void)
91 {
92         TDB_DATA kbuf, newkey, dbuf;
93
94         DEBUG(0,("upgrade_to_version_3: upgrading print tdb's to version 3\n"));
95
96         for (kbuf = tdb_firstkey(tdb_drivers); kbuf.dptr;
97              newkey = tdb_nextkey(tdb_drivers, kbuf), free(kbuf.dptr), kbuf=newkey) {
98
99                 dbuf = tdb_fetch(tdb_drivers, kbuf);
100
101                 if (strncmp((const char *)kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) == 0) {
102                         DEBUG(0,("upgrade_to_version_3:moving form\n"));
103                         if (tdb_store(tdb_forms, kbuf, dbuf, TDB_REPLACE) != 0) {
104                                 SAFE_FREE(dbuf.dptr);
105                                 DEBUG(0,("upgrade_to_version_3: failed to move form. Error (%s).\n", tdb_errorstr(tdb_forms)));
106                                 return False;
107                         }
108                         if (tdb_delete(tdb_drivers, kbuf) != 0) {
109                                 SAFE_FREE(dbuf.dptr);
110                                 DEBUG(0,("upgrade_to_version_3: failed to delete form. Error (%s)\n", tdb_errorstr(tdb_drivers)));
111                                 return False;
112                         }
113                 }
114
115                 if (strncmp((const char *)kbuf.dptr, PRINTERS_PREFIX, strlen(PRINTERS_PREFIX)) == 0) {
116                         DEBUG(0,("upgrade_to_version_3:moving printer\n"));
117                         if (tdb_store(tdb_printers, kbuf, dbuf, TDB_REPLACE) != 0) {
118                                 SAFE_FREE(dbuf.dptr);
119                                 DEBUG(0,("upgrade_to_version_3: failed to move printer. Error (%s)\n", tdb_errorstr(tdb_printers)));
120                                 return False;
121                         }
122                         if (tdb_delete(tdb_drivers, kbuf) != 0) {
123                                 SAFE_FREE(dbuf.dptr);
124                                 DEBUG(0,("upgrade_to_version_3: failed to delete printer. Error (%s)\n", tdb_errorstr(tdb_drivers)));
125                                 return False;
126                         }
127                 }
128
129                 if (strncmp((const char *)kbuf.dptr, SECDESC_PREFIX, strlen(SECDESC_PREFIX)) == 0) {
130                         DEBUG(0,("upgrade_to_version_3:moving secdesc\n"));
131                         if (tdb_store(tdb_printers, kbuf, dbuf, TDB_REPLACE) != 0) {
132                                 SAFE_FREE(dbuf.dptr);
133                                 DEBUG(0,("upgrade_to_version_3: failed to move secdesc. Error (%s)\n", tdb_errorstr(tdb_printers)));
134                                 return False;
135                         }
136                         if (tdb_delete(tdb_drivers, kbuf) != 0) {
137                                 SAFE_FREE(dbuf.dptr);
138                                 DEBUG(0,("upgrade_to_version_3: failed to delete secdesc. Error (%s)\n", tdb_errorstr(tdb_drivers)));
139                                 return False;
140                         }
141                 }
142
143                 SAFE_FREE(dbuf.dptr);
144         }
145
146         return True;
147 }
148
149 /*******************************************************************
150  Fix an issue with security descriptors.  Printer sec_desc must
151  use more than the generic bits that were previously used
152  in <= 3.0.14a.  They must also have a owner and group SID assigned.
153  Otherwise, any printers than have been migrated to a Windows
154  host using printmig.exe will not be accessible.
155 *******************************************************************/
156
157 static int sec_desc_upg_fn( TDB_CONTEXT *the_tdb, TDB_DATA key,
158                             TDB_DATA data, void *state )
159 {
160         NTSTATUS status;
161         struct sec_desc_buf *sd_orig = NULL;
162         struct sec_desc_buf *sd_new, *sd_store;
163         struct security_descriptor *sec, *new_sec;
164         TALLOC_CTX *ctx = state;
165         int result, i;
166         size_t size_new_sec;
167
168         if (!data.dptr || data.dsize == 0) {
169                 return 0;
170         }
171
172         if ( strncmp((const char *) key.dptr, SECDESC_PREFIX, strlen(SECDESC_PREFIX) ) != 0 ) {
173                 return 0;
174         }
175
176         /* upgrade the security descriptor */
177
178         status = unmarshall_sec_desc_buf(ctx, data.dptr, data.dsize, &sd_orig);
179         if (!NT_STATUS_IS_OK(status)) {
180                 /* delete bad entries */
181                 DEBUG(0,("sec_desc_upg_fn: Failed to parse original sec_desc for %si.  Deleting....\n",
182                         (const char *)key.dptr ));
183                 tdb_delete( tdb_printers, key );
184                 return 0;
185         }
186
187         if (!sd_orig) {
188                 return 0;
189         }
190         sec = sd_orig->sd;
191
192         /* is this even valid? */
193
194         if ( !sec->dacl ) {
195                 return 0;
196         }
197
198         /* update access masks */
199
200         for ( i=0; i<sec->dacl->num_aces; i++ ) {
201                 switch ( sec->dacl->aces[i].access_mask ) {
202                         case (GENERIC_READ_ACCESS | GENERIC_WRITE_ACCESS | GENERIC_EXECUTE_ACCESS):
203                                 sec->dacl->aces[i].access_mask = PRINTER_ACE_PRINT;
204                                 break;
205
206                         case GENERIC_ALL_ACCESS:
207                                 sec->dacl->aces[i].access_mask = PRINTER_ACE_FULL_CONTROL;
208                                 break;
209
210                         case READ_CONTROL_ACCESS:
211                                 sec->dacl->aces[i].access_mask = PRINTER_ACE_MANAGE_DOCUMENTS;
212
213                                 break;
214                         default:        /* no change */
215                                 break;
216                 }
217         }
218
219         /* create a new struct security_descriptor with the appropriate owner and group SIDs */
220
221         new_sec = make_sec_desc( ctx, SD_REVISION, SEC_DESC_SELF_RELATIVE,
222                                  &global_sid_Builtin_Administrators,
223                                  &global_sid_Builtin_Administrators,
224                                  NULL, NULL, &size_new_sec );
225         if (!new_sec) {
226                 return 0;
227         }
228         sd_new = make_sec_desc_buf( ctx, size_new_sec, new_sec );
229         if (!sd_new) {
230                 return 0;
231         }
232
233         if ( !(sd_store = sec_desc_merge_buf( ctx, sd_new, sd_orig )) ) {
234                 DEBUG(0,("sec_desc_upg_fn: Failed to update sec_desc for %s\n", key.dptr ));
235                 return 0;
236         }
237
238         /* store it back */
239
240         status = marshall_sec_desc_buf(ctx, sd_store, &data.dptr, &data.dsize);
241         if (!NT_STATUS_IS_OK(status)) {
242                 DEBUG(0,("sec_desc_upg_fn: Failed to parse new sec_desc for %s\n", key.dptr ));
243                 return 0;
244         }
245
246         result = tdb_store( tdb_printers, key, data, TDB_REPLACE );
247
248         /* 0 to continue and non-zero to stop traversal */
249
250         return (result != 0);
251 }
252
253 /*******************************************************************
254  Upgrade the tdb files to version 4
255 *******************************************************************/
256
257 static bool upgrade_to_version_4(void)
258 {
259         TALLOC_CTX *ctx;
260         int result;
261
262         DEBUG(0,("upgrade_to_version_4: upgrading printer security descriptors\n"));
263
264         if ( !(ctx = talloc_init( "upgrade_to_version_4" )) )
265                 return False;
266
267         result = tdb_traverse( tdb_printers, sec_desc_upg_fn, ctx );
268
269         talloc_destroy( ctx );
270
271         return ( result >= 0 );
272 }
273
274 /*******************************************************************
275  Fix an issue with security descriptors.  Printer sec_desc must
276  use more than the generic bits that were previously used
277  in <= 3.0.14a.  They must also have a owner and group SID assigned.
278  Otherwise, any printers than have been migrated to a Windows
279  host using printmig.exe will not be accessible.
280 *******************************************************************/
281
282 static int normalize_printers_fn( TDB_CONTEXT *the_tdb, TDB_DATA key,
283                                   TDB_DATA data, void *state )
284 {
285         TALLOC_CTX *ctx = talloc_tos();
286         TDB_DATA new_key;
287
288         if (!data.dptr || data.dsize == 0)
289                 return 0;
290
291         /* upgrade printer records and security descriptors */
292
293         if ( strncmp((const char *) key.dptr, PRINTERS_PREFIX, strlen(PRINTERS_PREFIX) ) == 0 ) {
294                 new_key = make_printer_tdbkey(ctx, (const char *)key.dptr+strlen(PRINTERS_PREFIX) );
295         }
296         else if ( strncmp((const char *) key.dptr, SECDESC_PREFIX, strlen(SECDESC_PREFIX) ) == 0 ) {
297                 new_key = make_printers_secdesc_tdbkey(ctx, (const char *)key.dptr+strlen(SECDESC_PREFIX) );
298         }
299         else {
300                 /* ignore this record */
301                 return 0;
302         }
303
304         /* delete the original record and store under the normalized key */
305
306         if ( tdb_delete( the_tdb, key ) != 0 ) {
307                 DEBUG(0,("normalize_printers_fn: tdb_delete for [%s] failed!\n",
308                         key.dptr));
309                 return 1;
310         }
311
312         if ( tdb_store( the_tdb, new_key, data, TDB_REPLACE) != 0 ) {
313                 DEBUG(0,("normalize_printers_fn: failed to store new record for [%s]!\n",
314                         key.dptr));
315                 return 1;
316         }
317
318         return 0;
319 }
320
321 /*******************************************************************
322  Upgrade the tdb files to version 5
323 *******************************************************************/
324
325 static bool upgrade_to_version_5(void)
326 {
327         TALLOC_CTX *ctx;
328         int result;
329
330         DEBUG(0,("upgrade_to_version_5: normalizing printer keys\n"));
331
332         if ( !(ctx = talloc_init( "upgrade_to_version_5" )) )
333                 return False;
334
335         result = tdb_traverse( tdb_printers, normalize_printers_fn, NULL );
336
337         talloc_destroy( ctx );
338
339         return ( result >= 0 );
340 }
341
342 bool nt_printing_tdb_upgrade(void)
343 {
344         char *drivers_path;
345         char *printers_path;
346         char *forms_path;
347         bool drivers_exists;
348         bool printers_exists;
349         bool forms_exists;
350         const char *vstring = "INFO/version";
351         int32_t vers_id;
352         bool ret;
353
354         drivers_path = state_path(talloc_tos(), "ntdrivers.tdb");
355         if (drivers_path == NULL) {
356                 ret = false;
357                 goto err_out;
358         }
359         printers_path = state_path(talloc_tos(), "ntprinters.tdb");
360         if (printers_path == NULL) {
361                 ret = false;
362                 goto err_drvdb_free;
363         }
364         forms_path = state_path(talloc_tos(), "ntforms.tdb");
365         if (forms_path == NULL) {
366                 ret = false;
367                 goto err_prdb_free;
368         }
369
370         drivers_exists = file_exist(drivers_path);
371         printers_exists = file_exist(printers_path);
372         forms_exists = file_exist(forms_path);
373
374         if (!drivers_exists && !printers_exists && !forms_exists) {
375                 ret = true;
376                 goto err_formsdb_free;
377         }
378
379         tdb_drivers = tdb_open_log(drivers_path,
380                                    0,
381                                    TDB_DEFAULT,
382                                    O_RDWR|O_CREAT,
383                                    0600);
384         if (tdb_drivers == NULL) {
385                 DEBUG(0,("nt_printing_init: Failed to open nt drivers "
386                          "database %s (%s)\n",
387                          drivers_path, strerror(errno)));
388                 ret = false;
389                 goto err_formsdb_free;
390         }
391
392         tdb_printers = tdb_open_log(printers_path,
393                                     0,
394                                     TDB_DEFAULT,
395                                     O_RDWR|O_CREAT,
396                                     0600);
397         if (tdb_printers == NULL) {
398                 DEBUG(0,("nt_printing_init: Failed to open nt printers "
399                          "database %s (%s)\n",
400                          printers_path, strerror(errno)));
401                 ret = false;
402                 goto err_drvdb_close;
403         }
404
405         tdb_forms = tdb_open_log(forms_path,
406                                  0,
407                                  TDB_DEFAULT,
408                                  O_RDWR|O_CREAT,
409                                  0600);
410         if (tdb_forms == NULL) {
411                 DEBUG(0,("nt_printing_init: Failed to open nt forms "
412                          "database %s (%s)\n",
413                          forms_path, strerror(errno)));
414                 ret = false;
415                 goto err_prdb_close;
416         }
417
418         /* Samba upgrade */
419         vers_id = tdb_fetch_int32(tdb_drivers, vstring);
420         if (vers_id == -1) {
421                 DEBUG(10, ("Fresh database\n"));
422                 tdb_store_int32(tdb_drivers, vstring, NTDRIVERS_DATABASE_VERSION_5);
423                 vers_id = NTDRIVERS_DATABASE_VERSION_5;
424         }
425
426         if (vers_id != NTDRIVERS_DATABASE_VERSION_5) {
427                 if ((vers_id == NTDRIVERS_DATABASE_VERSION_1) ||
428                     (IREV(vers_id) == NTDRIVERS_DATABASE_VERSION_1)) {
429                         if (!upgrade_to_version_3()) {
430                                 ret = false;
431                                 goto err_formsdb_close;
432                         }
433
434                         tdb_store_int32(tdb_drivers, vstring, NTDRIVERS_DATABASE_VERSION_3);
435                         vers_id = NTDRIVERS_DATABASE_VERSION_3;
436                 }
437
438                 if ((vers_id == NTDRIVERS_DATABASE_VERSION_2) ||
439                     (IREV(vers_id) == NTDRIVERS_DATABASE_VERSION_2)) {
440                         /*
441                          * Written on a bigendian machine with old fetch_int
442                          * code. Save as le. The only upgrade between V2 and V3
443                          * is to save the version in little-endian.
444                          */
445                         tdb_store_int32(tdb_drivers, vstring, NTDRIVERS_DATABASE_VERSION_3);
446                         vers_id = NTDRIVERS_DATABASE_VERSION_3;
447                 }
448
449                 if (vers_id == NTDRIVERS_DATABASE_VERSION_3) {
450                         if (!upgrade_to_version_4()) {
451                                 ret = false;
452                                 goto err_formsdb_close;
453                         }
454                         tdb_store_int32(tdb_drivers, vstring, NTDRIVERS_DATABASE_VERSION_4);
455                         vers_id = NTDRIVERS_DATABASE_VERSION_4;
456                 }
457
458                 if (vers_id == NTDRIVERS_DATABASE_VERSION_4 ) {
459                         if (!upgrade_to_version_5()) {
460                                 ret = false;
461                                 goto err_formsdb_close;
462                         }
463                         tdb_store_int32(tdb_drivers, vstring, NTDRIVERS_DATABASE_VERSION_5);
464                         vers_id = NTDRIVERS_DATABASE_VERSION_5;
465                 }
466
467                 if (vers_id != NTDRIVERS_DATABASE_VERSION_5) {
468                         DEBUG(0,("nt_printing_init: Unknown printer database version [%d]\n", vers_id));
469                         ret = false;
470                         goto err_formsdb_close;
471                 }
472         }
473         ret = true;
474
475 err_formsdb_close:
476         if (tdb_forms) {
477                 tdb_close(tdb_forms);
478                 tdb_forms = NULL;
479         }
480 err_prdb_close:
481         if (tdb_printers) {
482                 tdb_close(tdb_printers);
483                 tdb_printers = NULL;
484         }
485 err_drvdb_close:
486         if (tdb_drivers) {
487                 tdb_close(tdb_drivers);
488                 tdb_drivers = NULL;
489         }
490 err_formsdb_free:
491         talloc_free(forms_path);
492 err_prdb_free:
493         talloc_free(printers_path);
494 err_drvdb_free:
495         talloc_free(drivers_path);
496 err_out:
497         return ret;
498 }