s3: only include tdb headers where needed.
[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
31 #define FORMS_PREFIX "FORMS/"
32 #define DRIVERS_PREFIX "DRIVERS/"
33 #define PRINTERS_PREFIX "PRINTERS/"
34 #define SECDESC_PREFIX "SECDESC/"
35
36 #define NTDRIVERS_DATABASE_VERSION_1 1
37 #define NTDRIVERS_DATABASE_VERSION_2 2
38 #define NTDRIVERS_DATABASE_VERSION_3 3 /* little endian version of v2 */
39 #define NTDRIVERS_DATABASE_VERSION_4 4 /* fix generic bits in security descriptors */
40 #define NTDRIVERS_DATABASE_VERSION_5 5 /* normalize keys in ntprinters.tdb */
41
42 static TDB_CONTEXT *tdb_forms; /* used for forms files */
43 static TDB_CONTEXT *tdb_drivers; /* used for driver files */
44 static TDB_CONTEXT *tdb_printers; /* used for printers files */
45
46 /****************************************************************************
47  generate a new TDB_DATA key for storing a printer
48 ****************************************************************************/
49
50 static TDB_DATA make_printer_tdbkey(TALLOC_CTX *ctx, const char *sharename )
51 {
52         fstring share;
53         char *keystr = NULL;
54         TDB_DATA key;
55
56         fstrcpy(share, sharename);
57         strlower_m(share);
58
59         keystr = talloc_asprintf(ctx, "%s%s", PRINTERS_PREFIX, share);
60         key = string_term_tdb_data(keystr ? keystr : "");
61
62         return key;
63 }
64
65 /****************************************************************************
66  generate a new TDB_DATA key for storing a printer security descriptor
67 ****************************************************************************/
68
69 static TDB_DATA make_printers_secdesc_tdbkey(TALLOC_CTX *ctx,
70                                         const char* sharename  )
71 {
72         fstring share;
73         char *keystr = NULL;
74         TDB_DATA key;
75
76         fstrcpy(share, sharename );
77         strlower_m(share);
78
79         keystr = talloc_asprintf(ctx, "%s%s", SECDESC_PREFIX, share);
80         key = string_term_tdb_data(keystr ? keystr : "");
81
82         return key;
83 }
84
85 /****************************************************************************
86  Upgrade the tdb files to version 3
87 ****************************************************************************/
88
89 static bool upgrade_to_version_3(void)
90 {
91         TDB_DATA kbuf, newkey, dbuf;
92
93         DEBUG(0,("upgrade_to_version_3: upgrading print tdb's to version 3\n"));
94
95         for (kbuf = tdb_firstkey(tdb_drivers); kbuf.dptr;
96                         newkey = tdb_nextkey(tdb_drivers, kbuf), free(kbuf.dptr), kbuf=newkey) {
97
98                 dbuf = tdb_fetch(tdb_drivers, kbuf);
99
100                 if (strncmp((const char *)kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) == 0) {
101                         DEBUG(0,("upgrade_to_version_3:moving form\n"));
102                         if (tdb_store(tdb_forms, kbuf, dbuf, TDB_REPLACE) != 0) {
103                                 SAFE_FREE(dbuf.dptr);
104                                 DEBUG(0,("upgrade_to_version_3: failed to move form. Error (%s).\n", tdb_errorstr(tdb_forms)));
105                                 return False;
106                         }
107                         if (tdb_delete(tdb_drivers, kbuf) != 0) {
108                                 SAFE_FREE(dbuf.dptr);
109                                 DEBUG(0,("upgrade_to_version_3: failed to delete form. Error (%s)\n", tdb_errorstr(tdb_drivers)));
110                                 return False;
111                         }
112                 }
113
114                 if (strncmp((const char *)kbuf.dptr, PRINTERS_PREFIX, strlen(PRINTERS_PREFIX)) == 0) {
115                         DEBUG(0,("upgrade_to_version_3:moving printer\n"));
116                         if (tdb_store(tdb_printers, kbuf, dbuf, TDB_REPLACE) != 0) {
117                                 SAFE_FREE(dbuf.dptr);
118                                 DEBUG(0,("upgrade_to_version_3: failed to move printer. Error (%s)\n", tdb_errorstr(tdb_printers)));
119                                 return False;
120                         }
121                         if (tdb_delete(tdb_drivers, kbuf) != 0) {
122                                 SAFE_FREE(dbuf.dptr);
123                                 DEBUG(0,("upgrade_to_version_3: failed to delete printer. Error (%s)\n", tdb_errorstr(tdb_drivers)));
124                                 return False;
125                         }
126                 }
127
128                 if (strncmp((const char *)kbuf.dptr, SECDESC_PREFIX, strlen(SECDESC_PREFIX)) == 0) {
129                         DEBUG(0,("upgrade_to_version_3:moving secdesc\n"));
130                         if (tdb_store(tdb_printers, kbuf, dbuf, TDB_REPLACE) != 0) {
131                                 SAFE_FREE(dbuf.dptr);
132                                 DEBUG(0,("upgrade_to_version_3: failed to move secdesc. Error (%s)\n", tdb_errorstr(tdb_printers)));
133                                 return False;
134                         }
135                         if (tdb_delete(tdb_drivers, kbuf) != 0) {
136                                 SAFE_FREE(dbuf.dptr);
137                                 DEBUG(0,("upgrade_to_version_3: failed to delete secdesc. Error (%s)\n", tdb_errorstr(tdb_drivers)));
138                                 return False;
139                         }
140                 }
141
142                 SAFE_FREE(dbuf.dptr);
143         }
144
145         return True;
146 }
147
148 /*******************************************************************
149  Fix an issue with security descriptors.  Printer sec_desc must
150  use more than the generic bits that were previously used
151  in <= 3.0.14a.  They must also have a owner and group SID assigned.
152  Otherwise, any printers than have been migrated to a Windows
153  host using printmig.exe will not be accessible.
154 *******************************************************************/
155
156 static int sec_desc_upg_fn( TDB_CONTEXT *the_tdb, TDB_DATA key,
157                             TDB_DATA data, void *state )
158 {
159         NTSTATUS status;
160         struct sec_desc_buf *sd_orig = NULL;
161         struct sec_desc_buf *sd_new, *sd_store;
162         struct security_descriptor *sec, *new_sec;
163         TALLOC_CTX *ctx = state;
164         int result, i;
165         uint32 sd_size;
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                         default:        /* no change */
214                                 break;
215                 }
216         }
217
218         /* create a new struct security_descriptor with the appropriate owner and group SIDs */
219
220         new_sec = make_sec_desc( ctx, SD_REVISION, SEC_DESC_SELF_RELATIVE,
221                                  &global_sid_Builtin_Administrators,
222                                  &global_sid_Builtin_Administrators,
223                                  NULL, NULL, &size_new_sec );
224         if (!new_sec) {
225                 return 0;
226         }
227         sd_new = make_sec_desc_buf( ctx, size_new_sec, new_sec );
228         if (!sd_new) {
229                 return 0;
230         }
231
232         if ( !(sd_store = sec_desc_merge_buf( ctx, sd_new, sd_orig )) ) {
233                 DEBUG(0,("sec_desc_upg_fn: Failed to update sec_desc for %s\n", key.dptr ));
234                 return 0;
235         }
236
237         /* store it back */
238
239         sd_size = ndr_size_security_descriptor(sd_store->sd, 0)
240                 + sizeof(struct sec_desc_buf);
241
242         status = marshall_sec_desc_buf(ctx, sd_store, &data.dptr, &data.dsize);
243         if (!NT_STATUS_IS_OK(status)) {
244                 DEBUG(0,("sec_desc_upg_fn: Failed to parse new sec_desc for %s\n", key.dptr ));
245                 return 0;
246         }
247
248         result = tdb_store( tdb_printers, key, data, TDB_REPLACE );
249
250         /* 0 to continue and non-zero to stop traversal */
251
252         return (result == -1);
253 }
254
255 /*******************************************************************
256  Upgrade the tdb files to version 4
257 *******************************************************************/
258
259 static bool upgrade_to_version_4(void)
260 {
261         TALLOC_CTX *ctx;
262         int result;
263
264         DEBUG(0,("upgrade_to_version_4: upgrading printer security descriptors\n"));
265
266         if ( !(ctx = talloc_init( "upgrade_to_version_4" )) )
267                 return False;
268
269         result = tdb_traverse( tdb_printers, sec_desc_upg_fn, ctx );
270
271         talloc_destroy( ctx );
272
273         return ( result != -1 );
274 }
275
276 /*******************************************************************
277  Fix an issue with security descriptors.  Printer sec_desc must
278  use more than the generic bits that were previously used
279  in <= 3.0.14a.  They must also have a owner and group SID assigned.
280  Otherwise, any printers than have been migrated to a Windows
281  host using printmig.exe will not be accessible.
282 *******************************************************************/
283
284 static int normalize_printers_fn( TDB_CONTEXT *the_tdb, TDB_DATA key,
285                                   TDB_DATA data, void *state )
286 {
287         TALLOC_CTX *ctx = talloc_tos();
288         TDB_DATA new_key;
289
290         if (!data.dptr || data.dsize == 0)
291                 return 0;
292
293         /* upgrade printer records and security descriptors */
294
295         if ( strncmp((const char *) key.dptr, PRINTERS_PREFIX, strlen(PRINTERS_PREFIX) ) == 0 ) {
296                 new_key = make_printer_tdbkey(ctx, (const char *)key.dptr+strlen(PRINTERS_PREFIX) );
297         }
298         else if ( strncmp((const char *) key.dptr, SECDESC_PREFIX, strlen(SECDESC_PREFIX) ) == 0 ) {
299                 new_key = make_printers_secdesc_tdbkey(ctx, (const char *)key.dptr+strlen(SECDESC_PREFIX) );
300         }
301         else {
302                 /* ignore this record */
303                 return 0;
304         }
305
306         /* delete the original record and store under the normalized key */
307
308         if ( tdb_delete( the_tdb, key ) != 0 ) {
309                 DEBUG(0,("normalize_printers_fn: tdb_delete for [%s] failed!\n",
310                         key.dptr));
311                 return 1;
312         }
313
314         if ( tdb_store( the_tdb, new_key, data, TDB_REPLACE) != 0 ) {
315                 DEBUG(0,("normalize_printers_fn: failed to store new record for [%s]!\n",
316                         key.dptr));
317                 return 1;
318         }
319
320         return 0;
321 }
322
323 /*******************************************************************
324  Upgrade the tdb files to version 5
325 *******************************************************************/
326
327 static bool upgrade_to_version_5(void)
328 {
329         TALLOC_CTX *ctx;
330         int result;
331
332         DEBUG(0,("upgrade_to_version_5: normalizing printer keys\n"));
333
334         if ( !(ctx = talloc_init( "upgrade_to_version_5" )) )
335                 return False;
336
337         result = tdb_traverse( tdb_printers, normalize_printers_fn, NULL );
338
339         talloc_destroy( ctx );
340
341         return ( result != -1 );
342 }
343
344 bool nt_printing_tdb_upgrade(void)
345 {
346         const char *drivers_path = state_path("ntdrivers.tdb");
347         const char *printers_path = state_path("ntprinters.tdb");
348         const char *forms_path = state_path("ntforms.tdb");
349         bool drivers_exists = file_exist(drivers_path);
350         bool printers_exists = file_exist(printers_path);
351         bool forms_exists = file_exist(forms_path);
352         const char *vstring = "INFO/version";
353         int32_t vers_id;
354
355         if (!drivers_exists && !printers_exists && !forms_exists) {
356                 return true;
357         }
358
359         tdb_drivers = tdb_open_log(drivers_path,
360                                    0,
361                                    TDB_DEFAULT,
362                                    O_RDWR|O_CREAT,
363                                    0600);
364         if (tdb_drivers == NULL) {
365                 DEBUG(0,("nt_printing_init: Failed to open nt drivers "
366                          "database %s (%s)\n",
367                          drivers_path, strerror(errno)));
368                 return false;
369         }
370
371         tdb_printers = tdb_open_log(printers_path,
372                                     0,
373                                     TDB_DEFAULT,
374                                     O_RDWR|O_CREAT,
375                                     0600);
376         if (tdb_printers == NULL) {
377                 DEBUG(0,("nt_printing_init: Failed to open nt printers "
378                          "database %s (%s)\n",
379                          printers_path, strerror(errno)));
380                 return false;
381         }
382
383         tdb_forms = tdb_open_log(forms_path,
384                                  0,
385                                  TDB_DEFAULT,
386                                  O_RDWR|O_CREAT,
387                                  0600);
388         if (tdb_forms == NULL) {
389                 DEBUG(0,("nt_printing_init: Failed to open nt forms "
390                          "database %s (%s)\n",
391                          forms_path, strerror(errno)));
392                 return false;
393         }
394
395         /* Samba upgrade */
396         vers_id = tdb_fetch_int32(tdb_drivers, vstring);
397         if (vers_id == -1) {
398                 DEBUG(10, ("Fresh database\n"));
399                 tdb_store_int32(tdb_drivers, vstring, NTDRIVERS_DATABASE_VERSION_5);
400                 vers_id = NTDRIVERS_DATABASE_VERSION_5;
401         }
402
403         if (vers_id != NTDRIVERS_DATABASE_VERSION_5) {
404                 if ((vers_id == NTDRIVERS_DATABASE_VERSION_1) ||
405                     (IREV(vers_id) == NTDRIVERS_DATABASE_VERSION_1)) {
406                         if (!upgrade_to_version_3()) {
407                                 return false;
408                         }
409
410                         tdb_store_int32(tdb_drivers, vstring, NTDRIVERS_DATABASE_VERSION_3);
411                         vers_id = NTDRIVERS_DATABASE_VERSION_3;
412                 }
413
414                 if ((vers_id == NTDRIVERS_DATABASE_VERSION_2) ||
415                     (IREV(vers_id) == NTDRIVERS_DATABASE_VERSION_2)) {
416                         /*
417                          * Written on a bigendian machine with old fetch_int
418                          * code. Save as le. The only upgrade between V2 and V3
419                          * is to save the version in little-endian.
420                          */
421                         tdb_store_int32(tdb_drivers, vstring, NTDRIVERS_DATABASE_VERSION_3);
422                         vers_id = NTDRIVERS_DATABASE_VERSION_3;
423                 }
424
425                 if (vers_id == NTDRIVERS_DATABASE_VERSION_3) {
426                         if (!upgrade_to_version_4()) {
427                                 return false;
428                         }
429                         tdb_store_int32(tdb_drivers, vstring, NTDRIVERS_DATABASE_VERSION_4);
430                         vers_id = NTDRIVERS_DATABASE_VERSION_4;
431                 }
432
433                 if (vers_id == NTDRIVERS_DATABASE_VERSION_4 ) {
434                         if (!upgrade_to_version_5()) {
435                                 return false;
436                         }
437                         tdb_store_int32(tdb_drivers, vstring, NTDRIVERS_DATABASE_VERSION_5);
438                         vers_id = NTDRIVERS_DATABASE_VERSION_5;
439                 }
440
441                 if (vers_id != NTDRIVERS_DATABASE_VERSION_5) {
442                         DEBUG(0,("nt_printing_init: Unknown printer database version [%d]\n", vers_id));
443                         return false;
444                 }
445         }
446
447         if (tdb_drivers) {
448                 tdb_close(tdb_drivers);
449                 tdb_drivers = NULL;
450         }
451
452         if (tdb_printers) {
453                 tdb_close(tdb_printers);
454                 tdb_printers = NULL;
455         }
456
457         if (tdb_forms) {
458                 tdb_close(tdb_forms);
459                 tdb_forms = NULL;
460         }
461
462         return true;
463 }