s3:smbd/oplock: pass sconn as private_data to process_oplock_async_level2_break_message()
[kai/samba.git] / source3 / registry / reg_backend_printing.c
1 /*
2  *  Unix SMB/CIFS implementation.
3  *  Virtual Windows Registry Layer
4  *  Copyright (C) Gerald Carter                     2002-2005
5  *  Copyright (c) Andreas Schneider <asn@samba.org> 2010
6  *
7  *  This program is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License as published by
9  *  the Free Software Foundation; either version 3 of the License, or
10  *  (at your option) any later version.
11  *
12  *  This program is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *  GNU General Public License for more details.
16  *
17  *  You should have received a copy of the GNU General Public License
18  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
19  */
20
21 /* Implementation of registry virtual views for printing information */
22
23 #include "includes.h"
24 #include "registry.h"
25 #include "reg_util_internal.h"
26 #include "reg_backend_db.h"
27
28 #undef DBGC_CLASS
29 #define DBGC_CLASS DBGC_REGISTRY
30
31 /* registry paths used in the print_registry[] */
32 #define KEY_CONTROL_PRINTERS    "HKLM\\SYSTEM\\CURRENTCONTROLSET\\CONTROL\\PRINT\\PRINTERS"
33 #define KEY_WINNT_PRINTERS      "HKLM\\SOFTWARE\\MICROSOFT\\WINDOWS NT\\CURRENTVERSION\\PRINT\\PRINTERS"
34
35 /* callback table for various registry paths below the ones we service in this module */
36
37 struct reg_dyn_tree {
38         /* full key path in normalized form */
39         const char *path;
40
41         /* callbscks for fetch/store operations */
42         int ( *fetch_subkeys) ( const char *path, struct regsubkey_ctr *subkeys );
43         bool (*store_subkeys) ( const char *path, struct regsubkey_ctr *subkeys );
44         int  (*fetch_values)  ( const char *path, struct regval_ctr *values );
45         bool (*store_values)  ( const char *path, struct regval_ctr *values );
46 };
47
48 /*********************************************************************
49  *********************************************************************
50  ** "HKLM/SYSTEM/CURRENTCONTROLSET/CONTROL/PRINT/PRINTERS"
51  ** "HKLM/SOFTWARE/MICROSOFT/WINDOWS NT/CURRENTVERSION/PRINT/PRINTERS"
52  *********************************************************************
53  *********************************************************************/
54
55 static char *create_printer_registry_path(TALLOC_CTX *mem_ctx, const char *key) {
56         char *path;
57         char *subkey = NULL;
58
59         path = talloc_strdup(mem_ctx, key);
60         if (path == NULL) {
61                 return NULL;
62         }
63
64         path = normalize_reg_path(mem_ctx, path);
65         if (path == NULL) {
66                 return NULL;
67         }
68
69         if (strncmp(path, KEY_CONTROL_PRINTERS, strlen(KEY_CONTROL_PRINTERS)) == 0) {
70                 subkey = reg_remaining_path(mem_ctx, key + strlen(KEY_CONTROL_PRINTERS));
71                 if (subkey == NULL) {
72                         return NULL;
73                 }
74                 return talloc_asprintf(mem_ctx, "%s\\%s", KEY_WINNT_PRINTERS, subkey);
75         }
76
77         return NULL;
78 }
79
80 /*********************************************************************
81  *********************************************************************/
82
83 static int key_printers_fetch_keys( const char *key, struct regsubkey_ctr *subkeys )
84 {
85         TALLOC_CTX *ctx = talloc_tos();
86         char *printers_key;
87
88         printers_key = create_printer_registry_path(ctx, key);
89         if (printers_key == NULL) {
90                 /* normalize on the 'HKLM\SOFTWARE\....\Print\Printers' key */
91                 return regdb_fetch_keys(KEY_WINNT_PRINTERS, subkeys);
92         }
93
94         return regdb_fetch_keys(printers_key, subkeys);
95 }
96
97 /**********************************************************************
98  *********************************************************************/
99
100 static bool key_printers_store_keys( const char *key, struct regsubkey_ctr *subkeys )
101 {
102         TALLOC_CTX *ctx = talloc_tos();
103         char *printers_key;
104
105         printers_key = create_printer_registry_path(ctx, key);
106         if (printers_key == NULL) {
107                 /* normalize on the 'HKLM\SOFTWARE\....\Print\Printers' key */
108                 return regdb_store_keys(KEY_WINNT_PRINTERS, subkeys);
109         }
110
111         return regdb_store_keys(printers_key, subkeys);
112 }
113
114 /**********************************************************************
115  *********************************************************************/
116
117 static int key_printers_fetch_values(const char *key, struct regval_ctr *values)
118 {
119         TALLOC_CTX *ctx = talloc_tos();
120         char *printers_key;
121
122         printers_key = create_printer_registry_path(ctx, key);
123         if (printers_key == NULL) {
124                 /* normalize on the 'HKLM\SOFTWARE\....\Print\Printers' key */
125                 return regdb_fetch_values(KEY_WINNT_PRINTERS, values);
126         }
127
128         return regdb_fetch_values(printers_key, values);
129 }
130
131 /**********************************************************************
132  *********************************************************************/
133
134 static bool key_printers_store_values(const char *key, struct regval_ctr *values)
135 {
136         TALLOC_CTX *ctx = talloc_tos();
137         char *printers_key;
138
139         printers_key = create_printer_registry_path(ctx, key);
140         if (printers_key == NULL) {
141                 /* normalize on the 'HKLM\SOFTWARE\....\Print\Printers' key */
142                 return regdb_store_values(KEY_WINNT_PRINTERS, values);
143         }
144
145         return regdb_store_values(printers_key, values);
146 }
147
148 /**********************************************************************
149  *********************************************************************
150  ** Structure to hold dispatch table of ops for various printer keys.
151  ** Make sure to always store deeper keys along the same path first so
152  ** we ge a more specific match.
153  *********************************************************************
154  *********************************************************************/
155
156 static struct reg_dyn_tree print_registry[] = {
157 { KEY_CONTROL_PRINTERS,
158         &key_printers_fetch_keys,
159         &key_printers_store_keys,
160         &key_printers_fetch_values,
161         &key_printers_store_values },
162
163 { NULL, NULL, NULL, NULL, NULL }
164 };
165
166
167 /**********************************************************************
168  *********************************************************************
169  ** Main reg_printing interface functions
170  *********************************************************************
171  *********************************************************************/
172
173 /***********************************************************************
174  Lookup a key in the print_registry table, returning its index.
175  -1 on failure
176  **********************************************************************/
177
178 static int match_registry_path(const char *key)
179 {
180         int i;
181         char *path = NULL;
182         TALLOC_CTX *ctx = talloc_tos();
183
184         if ( !key )
185                 return -1;
186
187         path = talloc_strdup(ctx, key);
188         if (!path) {
189                 return -1;
190         }
191         path = normalize_reg_path(ctx, path);
192         if (!path) {
193                 return -1;
194         }
195
196         for ( i=0; print_registry[i].path; i++ ) {
197                 if (strncmp( path, print_registry[i].path, strlen(print_registry[i].path) ) == 0 )
198                         return i;
199         }
200
201         return -1;
202 }
203
204 /***********************************************************************
205  **********************************************************************/
206
207 static int regprint_fetch_reg_keys( const char *key, struct regsubkey_ctr *subkeys )
208 {
209         int i = match_registry_path( key );
210
211         if ( i == -1 )
212                 return -1;
213
214         if ( !print_registry[i].fetch_subkeys )
215                 return -1;
216
217         return print_registry[i].fetch_subkeys( key, subkeys );
218 }
219
220 /**********************************************************************
221  *********************************************************************/
222
223 static bool regprint_store_reg_keys( const char *key, struct regsubkey_ctr *subkeys )
224 {
225         int i = match_registry_path( key );
226
227         if ( i == -1 )
228                 return False;
229
230         if ( !print_registry[i].store_subkeys )
231                 return False;
232
233         return print_registry[i].store_subkeys( key, subkeys );
234 }
235
236 /**********************************************************************
237  *********************************************************************/
238
239 static int regprint_fetch_reg_values(const char *key, struct regval_ctr *values)
240 {
241         int i = match_registry_path( key );
242
243         if ( i == -1 )
244                 return -1;
245
246         /* return 0 values by default since we know the key had
247            to exist because the client opened a handle */
248
249         if ( !print_registry[i].fetch_values )
250                 return 0;
251
252         return print_registry[i].fetch_values( key, values );
253 }
254
255 /**********************************************************************
256  *********************************************************************/
257
258 static bool regprint_store_reg_values(const char *key, struct regval_ctr *values)
259 {
260         int i = match_registry_path( key );
261
262         if ( i == -1 )
263                 return False;
264
265         if ( !print_registry[i].store_values )
266                 return False;
267
268         return print_registry[i].store_values( key, values );
269 }
270
271 /*
272  * Table of function pointers for accessing printing data
273  */
274
275 struct registry_ops printing_ops = {
276         .fetch_subkeys = regprint_fetch_reg_keys,
277         .fetch_values = regprint_fetch_reg_values,
278         .store_subkeys = regprint_store_reg_keys,
279         .store_values = regprint_store_reg_values,
280 };