Line data Source code
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 :
27 : #undef DBGC_CLASS
28 : #define DBGC_CLASS DBGC_REGISTRY
29 :
30 : extern struct registry_ops regdb_ops;
31 :
32 : /* registry paths used in the print_registry[] */
33 : #define KEY_CONTROL_PRINTERS "HKLM\\SYSTEM\\CURRENTCONTROLSET\\CONTROL\\PRINT\\PRINTERS"
34 : #define KEY_WINNT_PRINTERS "HKLM\\SOFTWARE\\MICROSOFT\\WINDOWS NT\\CURRENTVERSION\\PRINT\\PRINTERS"
35 :
36 : /* callback table for various registry paths below the ones we service in this module */
37 :
38 : struct reg_dyn_tree {
39 : /* full key path in normalized form */
40 : const char *path;
41 :
42 : /* callbscks for fetch/store operations */
43 : int ( *fetch_subkeys) ( const char *path, struct regsubkey_ctr *subkeys );
44 : bool (*store_subkeys) ( const char *path, struct regsubkey_ctr *subkeys );
45 : int (*fetch_values) ( const char *path, struct regval_ctr *values );
46 : bool (*store_values) ( const char *path, struct regval_ctr *values );
47 : };
48 :
49 : /*********************************************************************
50 : *********************************************************************
51 : ** "HKLM/SYSTEM/CURRENTCONTROLSET/CONTROL/PRINT/PRINTERS"
52 : ** "HKLM/SOFTWARE/MICROSOFT/WINDOWS NT/CURRENTVERSION/PRINT/PRINTERS"
53 : *********************************************************************
54 : *********************************************************************/
55 :
56 240 : static char *create_printer_registry_path(TALLOC_CTX *mem_ctx, const char *key) {
57 0 : char *path;
58 240 : char *subkey = NULL;
59 :
60 240 : path = talloc_strdup(mem_ctx, key);
61 240 : if (path == NULL) {
62 0 : return NULL;
63 : }
64 :
65 240 : path = normalize_reg_path(mem_ctx, path);
66 240 : if (path == NULL) {
67 0 : return NULL;
68 : }
69 :
70 240 : if (strncmp(path, KEY_CONTROL_PRINTERS, strlen(KEY_CONTROL_PRINTERS)) == 0) {
71 240 : subkey = reg_remaining_path(mem_ctx, key + strlen(KEY_CONTROL_PRINTERS));
72 240 : if (subkey == NULL) {
73 8 : return NULL;
74 : }
75 232 : return talloc_asprintf(mem_ctx, "%s\\%s", KEY_WINNT_PRINTERS, subkey);
76 : }
77 :
78 0 : return NULL;
79 : }
80 :
81 : /*********************************************************************
82 : *********************************************************************/
83 :
84 16 : static int key_printers_fetch_keys( const char *key, struct regsubkey_ctr *subkeys )
85 : {
86 16 : TALLOC_CTX *ctx = talloc_tos();
87 0 : char *printers_key;
88 :
89 16 : printers_key = create_printer_registry_path(ctx, key);
90 16 : if (printers_key == NULL) {
91 : /* normalize on the 'HKLM\SOFTWARE\....\Print\Printers' key */
92 8 : return regdb_ops.fetch_subkeys(KEY_WINNT_PRINTERS, subkeys);
93 : }
94 :
95 8 : return regdb_ops.fetch_subkeys(printers_key, subkeys);
96 : }
97 :
98 : /**********************************************************************
99 : *********************************************************************/
100 :
101 0 : static bool key_printers_store_keys( const char *key, struct regsubkey_ctr *subkeys )
102 : {
103 0 : TALLOC_CTX *ctx = talloc_tos();
104 0 : char *printers_key;
105 :
106 0 : printers_key = create_printer_registry_path(ctx, key);
107 0 : if (printers_key == NULL) {
108 : /* normalize on the 'HKLM\SOFTWARE\....\Print\Printers' key */
109 0 : return regdb_ops.store_subkeys(KEY_WINNT_PRINTERS, subkeys);
110 : }
111 :
112 0 : return regdb_ops.store_subkeys(printers_key, subkeys);
113 : }
114 :
115 : /**********************************************************************
116 : *********************************************************************/
117 :
118 224 : static int key_printers_fetch_values(const char *key, struct regval_ctr *values)
119 : {
120 224 : TALLOC_CTX *ctx = talloc_tos();
121 0 : char *printers_key;
122 :
123 224 : printers_key = create_printer_registry_path(ctx, key);
124 224 : if (printers_key == NULL) {
125 : /* normalize on the 'HKLM\SOFTWARE\....\Print\Printers' key */
126 0 : return regdb_ops.fetch_values(KEY_WINNT_PRINTERS, values);
127 : }
128 :
129 224 : return regdb_ops.fetch_values(printers_key, values);
130 : }
131 :
132 : /**********************************************************************
133 : *********************************************************************/
134 :
135 0 : static bool key_printers_store_values(const char *key, struct regval_ctr *values)
136 : {
137 0 : TALLOC_CTX *ctx = talloc_tos();
138 0 : char *printers_key;
139 :
140 0 : printers_key = create_printer_registry_path(ctx, key);
141 0 : if (printers_key == NULL) {
142 : /* normalize on the 'HKLM\SOFTWARE\....\Print\Printers' key */
143 0 : return regdb_ops.store_values(KEY_WINNT_PRINTERS, values);
144 : }
145 :
146 0 : return regdb_ops.store_values(printers_key, values);
147 : }
148 :
149 : /**********************************************************************
150 : *********************************************************************
151 : ** Structure to hold dispatch table of ops for various printer keys.
152 : ** Make sure to always store deeper keys along the same path first so
153 : ** we ge a more specific match.
154 : *********************************************************************
155 : *********************************************************************/
156 :
157 : static struct reg_dyn_tree print_registry[] = {
158 : { KEY_CONTROL_PRINTERS,
159 : &key_printers_fetch_keys,
160 : &key_printers_store_keys,
161 : &key_printers_fetch_values,
162 : &key_printers_store_values },
163 :
164 : { NULL, NULL, NULL, NULL, NULL }
165 : };
166 :
167 :
168 : /**********************************************************************
169 : *********************************************************************
170 : ** Main reg_printing interface functions
171 : *********************************************************************
172 : *********************************************************************/
173 :
174 : /***********************************************************************
175 : Lookup a key in the print_registry table, returning its index.
176 : -1 on failure
177 : **********************************************************************/
178 :
179 240 : static int match_registry_path(const char *key)
180 : {
181 0 : int i;
182 240 : char *path = NULL;
183 240 : TALLOC_CTX *ctx = talloc_tos();
184 :
185 240 : if ( !key )
186 0 : return -1;
187 :
188 240 : path = talloc_strdup(ctx, key);
189 240 : if (!path) {
190 0 : return -1;
191 : }
192 240 : path = normalize_reg_path(ctx, path);
193 240 : if (!path) {
194 0 : return -1;
195 : }
196 :
197 240 : for ( i=0; print_registry[i].path; i++ ) {
198 240 : if (strncmp( path, print_registry[i].path, strlen(print_registry[i].path) ) == 0 )
199 240 : return i;
200 : }
201 :
202 0 : return -1;
203 : }
204 :
205 : /***********************************************************************
206 : **********************************************************************/
207 :
208 16 : static int regprint_fetch_reg_keys( const char *key, struct regsubkey_ctr *subkeys )
209 : {
210 16 : int i = match_registry_path( key );
211 :
212 16 : if ( i == -1 )
213 0 : return -1;
214 :
215 16 : if ( !print_registry[i].fetch_subkeys )
216 0 : return -1;
217 :
218 16 : return print_registry[i].fetch_subkeys( key, subkeys );
219 : }
220 :
221 : /**********************************************************************
222 : *********************************************************************/
223 :
224 0 : static bool regprint_store_reg_keys( const char *key, struct regsubkey_ctr *subkeys )
225 : {
226 0 : int i = match_registry_path( key );
227 :
228 0 : if ( i == -1 )
229 0 : return False;
230 :
231 0 : if ( !print_registry[i].store_subkeys )
232 0 : return False;
233 :
234 0 : return print_registry[i].store_subkeys( key, subkeys );
235 : }
236 :
237 : /**********************************************************************
238 : *********************************************************************/
239 :
240 224 : static int regprint_fetch_reg_values(const char *key, struct regval_ctr *values)
241 : {
242 224 : int i = match_registry_path( key );
243 :
244 224 : if ( i == -1 )
245 0 : return -1;
246 :
247 : /* return 0 values by default since we know the key had
248 : to exist because the client opened a handle */
249 :
250 224 : if ( !print_registry[i].fetch_values )
251 0 : return 0;
252 :
253 224 : return print_registry[i].fetch_values( key, values );
254 : }
255 :
256 : /**********************************************************************
257 : *********************************************************************/
258 :
259 0 : static bool regprint_store_reg_values(const char *key, struct regval_ctr *values)
260 : {
261 0 : int i = match_registry_path( key );
262 :
263 0 : if ( i == -1 )
264 0 : return False;
265 :
266 0 : if ( !print_registry[i].store_values )
267 0 : return False;
268 :
269 0 : return print_registry[i].store_values( key, values );
270 : }
271 :
272 : /*
273 : * Table of function pointers for accessing printing data
274 : */
275 :
276 : struct registry_ops printing_ops = {
277 : .fetch_subkeys = regprint_fetch_reg_keys,
278 : .fetch_values = regprint_fetch_reg_values,
279 : .store_subkeys = regprint_store_reg_keys,
280 : .store_values = regprint_store_reg_values,
281 : };
|