Prevent warning about directory already existing.
[tprouty/samba.git] / source4 / rpc_server / winreg / rpc_winreg.c
1 /*
2    Unix SMB/CIFS implementation.
3
4    endpoint server for the winreg pipe
5
6    Copyright (C) Jelmer Vernooij 2004
7
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 3 of the License, or
11    (at your option) any later version.
12
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.
17
18    You should have received a copy of the GNU General Public License
19    along with this program.  If not, see <http://www.gnu.org/licenses/>.
20 */
21
22 #include "includes.h"
23 #include "rpc_server/dcerpc_server.h"
24 #include "lib/registry/registry.h"
25 #include "librpc/gen_ndr/ndr_winreg.h"
26 #include "rpc_server/common/common.h"
27 #include "librpc/gen_ndr/ndr_security.h"
28 #include "param/param.h"
29 #include "libcli/security/security.h"
30
31 enum handle_types { HTYPE_REGVAL, HTYPE_REGKEY };
32
33 static NTSTATUS dcerpc_winreg_bind(struct dcesrv_call_state *dce_call,
34                                    const struct dcesrv_interface *iface)
35 {
36         struct registry_context *ctx;
37         WERROR err;
38
39         err = reg_open_samba(dce_call->context,
40                              &ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, dce_call->conn->auth_state.session_info,
41                              NULL);
42
43         if (!W_ERROR_IS_OK(err)) {
44                 DEBUG(0, ("Error opening registry: %s\n", win_errstr(err)));
45                 return NT_STATUS_UNSUCCESSFUL;
46         }
47
48         dce_call->context->private = ctx;
49
50         return NT_STATUS_OK;
51 }
52
53 #define DCESRV_INTERFACE_WINREG_BIND dcerpc_winreg_bind
54
55 static WERROR dcesrv_winreg_openhive(struct dcesrv_call_state *dce_call,
56                                      TALLOC_CTX *mem_ctx, uint32_t hkey,
57                                      struct policy_handle **outh)
58 {
59         struct registry_context *ctx = dce_call->context->private;
60         struct dcesrv_handle *h;
61         WERROR error;
62
63         h = dcesrv_handle_new(dce_call->context, HTYPE_REGKEY);
64
65         error = reg_get_predefined_key(ctx, hkey,
66                                        (struct registry_key **)&h->data);
67         if (!W_ERROR_IS_OK(error)) {
68                 return error;
69         }
70
71         *outh = &h->wire_handle;
72
73         return error;
74 }
75
76 #define func_winreg_OpenHive(k,n) static WERROR dcesrv_winreg_Open ## k (struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct winreg_Open ## k *r) \
77 { \
78         return dcesrv_winreg_openhive (dce_call, mem_ctx, n, &r->out.handle);\
79 }
80
81 func_winreg_OpenHive(HKCR,HKEY_CLASSES_ROOT)
82 func_winreg_OpenHive(HKCU,HKEY_CURRENT_USER)
83 func_winreg_OpenHive(HKLM,HKEY_LOCAL_MACHINE)
84 func_winreg_OpenHive(HKPD,HKEY_PERFORMANCE_DATA)
85 func_winreg_OpenHive(HKU,HKEY_USERS)
86 func_winreg_OpenHive(HKCC,HKEY_CURRENT_CONFIG)
87 func_winreg_OpenHive(HKDD,HKEY_DYN_DATA)
88 func_winreg_OpenHive(HKPT,HKEY_PERFORMANCE_TEXT)
89 func_winreg_OpenHive(HKPN,HKEY_PERFORMANCE_NLSTEXT)
90
91 /*
92   winreg_CloseKey
93 */
94 static WERROR dcesrv_winreg_CloseKey(struct dcesrv_call_state *dce_call,
95                                      TALLOC_CTX *mem_ctx,
96                                      struct winreg_CloseKey *r)
97 {
98         struct dcesrv_handle *h;
99
100         DCESRV_PULL_HANDLE_FAULT(h, r->in.handle, HTYPE_REGKEY);
101
102         talloc_free(h);
103
104         ZERO_STRUCTP(r->out.handle);
105
106         return WERR_OK;
107 }
108
109 /*
110   winreg_CreateKey
111 */
112 static WERROR dcesrv_winreg_CreateKey(struct dcesrv_call_state *dce_call,
113                                       TALLOC_CTX *mem_ctx,
114                                       struct winreg_CreateKey *r)
115 {
116         struct dcesrv_handle *h, *newh;
117         WERROR error;
118         struct security_descriptor sd;
119
120         DCESRV_PULL_HANDLE_FAULT(h, r->in.handle, HTYPE_REGKEY);
121
122         newh = dcesrv_handle_new(dce_call->context, HTYPE_REGKEY);
123
124         switch (security_session_user_level(dce_call->conn->auth_state.session_info))
125         {
126         case SECURITY_SYSTEM:
127         case SECURITY_ADMINISTRATOR:
128                 /* the security descriptor is optional */
129                 if (r->in.secdesc != NULL) {
130                         DATA_BLOB sdblob;
131                         enum ndr_err_code ndr_err;
132                         sdblob.data = r->in.secdesc->sd.data;
133                         sdblob.length = r->in.secdesc->sd.len;
134                         if (sdblob.data == NULL) {
135                                 return WERR_INVALID_PARAM;
136                         }
137                         ndr_err = ndr_pull_struct_blob_all(&sdblob, mem_ctx, NULL, &sd,
138                                                            (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
139                         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
140                                 return WERR_INVALID_PARAM;
141                         }
142                 }
143                 
144                 error = reg_key_add_name(newh, (struct registry_key *)h->data,
145                                          r->in.name.name, NULL, r->in.secdesc?&sd:NULL,
146                                          (struct registry_key **)&newh->data);
147                 if (W_ERROR_IS_OK(error)) {
148                         r->out.new_handle = &newh->wire_handle;
149                 } else {
150                         talloc_free(newh);
151                 }
152                 
153                 return error;
154         default:
155                 return WERR_ACCESS_DENIED;
156         }
157 }
158
159
160 /*
161   winreg_DeleteKey
162 */
163 static WERROR dcesrv_winreg_DeleteKey(struct dcesrv_call_state *dce_call,
164                                       TALLOC_CTX *mem_ctx,
165                                       struct winreg_DeleteKey *r)
166 {
167         struct dcesrv_handle *h;
168
169         DCESRV_PULL_HANDLE_FAULT(h, r->in.handle, HTYPE_REGKEY);
170
171         switch (security_session_user_level(dce_call->conn->auth_state.session_info))
172         {
173         case SECURITY_SYSTEM:
174         case SECURITY_ADMINISTRATOR:
175                 return reg_key_del((struct registry_key *)h->data, r->in.key.name);
176         default:
177                 return WERR_ACCESS_DENIED;
178         }
179 }
180
181
182 /*
183   winreg_DeleteValue
184 */
185 static WERROR dcesrv_winreg_DeleteValue(struct dcesrv_call_state *dce_call,
186                                         TALLOC_CTX *mem_ctx,
187                                         struct winreg_DeleteValue *r)
188 {
189         struct dcesrv_handle *h;
190         struct registry_key *key;
191
192         DCESRV_PULL_HANDLE_FAULT(h, r->in.handle, HTYPE_REGKEY);
193
194         switch (security_session_user_level(dce_call->conn->auth_state.session_info))
195         {
196         case SECURITY_SYSTEM:
197         case SECURITY_ADMINISTRATOR:
198                 key = h->data;
199                 
200                 return reg_del_value(key, r->in.value.name);
201         default:
202                 return WERR_ACCESS_DENIED;
203         }
204 }
205
206
207 /*
208   winreg_EnumKey
209 */
210 static WERROR dcesrv_winreg_EnumKey(struct dcesrv_call_state *dce_call,
211                                     TALLOC_CTX *mem_ctx,
212                                     struct winreg_EnumKey *r)
213 {
214         struct dcesrv_handle *h;
215         const char *name;
216         NTTIME last_mod;
217
218         DCESRV_PULL_HANDLE_FAULT(h, r->in.handle, HTYPE_REGKEY);
219
220         r->out.result = reg_key_get_subkey_by_index(mem_ctx,
221                                                     (struct registry_key *)h->data,
222                                                     r->in.enum_index,
223                                                     &name, NULL, &last_mod);
224
225         if (W_ERROR_IS_OK(r->out.result)) {
226                 if (2*strlen_m_term(name) > r->in.name->size) {
227                         return WERR_MORE_DATA;
228                 }
229                 r->out.name->length = 2*strlen_m_term(name);
230                 r->out.name->name = name;
231                 r->out.keyclass = talloc_zero(mem_ctx, struct winreg_StringBuf);
232                 if (r->in.last_changed_time) {
233                         r->out.last_changed_time = &last_mod;
234                 }
235         }
236
237         return r->out.result;
238 }
239
240
241 /*
242   winreg_EnumValue
243 */
244 static WERROR dcesrv_winreg_EnumValue(struct dcesrv_call_state *dce_call,
245                                       TALLOC_CTX *mem_ctx,
246                                       struct winreg_EnumValue *r)
247 {
248         struct dcesrv_handle *h;
249         struct registry_key *key;
250         WERROR result;
251         const char *data_name;
252         uint32_t data_type;
253         DATA_BLOB data;
254
255         DCESRV_PULL_HANDLE_FAULT(h, r->in.handle, HTYPE_REGKEY);
256
257         key = h->data;
258
259         result = reg_key_get_value_by_index(mem_ctx, key, r->in.enum_index,
260                                             &data_name,
261                                             &data_type, &data);
262         if (!W_ERROR_IS_OK(result)) {
263                 return result;
264         }
265
266         /* the client can optionally pass a NULL for type, meaning they don't
267            want that back */
268         if (r->in.type != NULL) {
269                 r->out.type = talloc(mem_ctx, enum winreg_Type);
270                 *r->out.type = data_type;
271         }
272
273         /* check the client has enough room for the value */
274         if (r->in.value != NULL &&
275             r->in.size != NULL &&
276             data.length > *r->in.size) {
277                 return WERR_MORE_DATA;
278         }
279
280         /* and enough room for the name */
281         if (r->in.name->size < 2*strlen_m_term(data_name)) {
282                 return WERR_MORE_DATA;
283         }
284
285         r->out.name->name = data_name;
286         r->out.name->length = 2*strlen_m_term(data_name);
287         r->out.name->size = r->in.name->size;
288
289         if (r->in.value) {
290                 r->out.value = data.data;
291         }
292
293         if (r->in.size) {
294                 r->out.size = talloc(mem_ctx, uint32_t);
295                 *r->out.size = data.length;
296                 r->out.length = r->out.size;
297         }
298
299         return WERR_OK;
300 }
301
302
303 /*
304   winreg_FlushKey
305 */
306 static WERROR dcesrv_winreg_FlushKey(struct dcesrv_call_state *dce_call,
307                                      TALLOC_CTX *mem_ctx,
308                                      struct winreg_FlushKey *r)
309 {
310         struct dcesrv_handle *h;
311
312         DCESRV_PULL_HANDLE_FAULT(h, r->in.handle, HTYPE_REGKEY);
313
314         switch (security_session_user_level(dce_call->conn->auth_state.session_info))
315         {
316         case SECURITY_SYSTEM:
317         case SECURITY_ADMINISTRATOR:
318                 return reg_key_flush(h->data);
319         default:
320                 return WERR_ACCESS_DENIED;
321         }
322 }
323
324
325 /*
326   winreg_GetKeySecurity
327 */
328 static WERROR dcesrv_winreg_GetKeySecurity(struct dcesrv_call_state *dce_call,
329                                            TALLOC_CTX *mem_ctx,
330                                            struct winreg_GetKeySecurity *r)
331 {
332         struct dcesrv_handle *h;
333
334         DCESRV_PULL_HANDLE_FAULT(h, r->in.handle, HTYPE_REGKEY);
335
336         return WERR_NOT_SUPPORTED;
337 }
338
339
340 /*
341   winreg_LoadKey
342 */
343 static WERROR dcesrv_winreg_LoadKey(struct dcesrv_call_state *dce_call,
344                                     TALLOC_CTX *mem_ctx,
345                                     struct winreg_LoadKey *r)
346 {
347         return WERR_NOT_SUPPORTED;
348 }
349
350
351 /*
352   winreg_NotifyChangeKeyValue
353 */
354 static WERROR dcesrv_winreg_NotifyChangeKeyValue(struct dcesrv_call_state *dce_call,
355                                                  TALLOC_CTX *mem_ctx,
356                                                  struct winreg_NotifyChangeKeyValue *r)
357 {
358         return WERR_NOT_SUPPORTED;
359 }
360
361
362 /*
363   winreg_OpenKey
364 */
365 static WERROR dcesrv_winreg_OpenKey(struct dcesrv_call_state *dce_call,
366                                     TALLOC_CTX *mem_ctx,
367                                     struct winreg_OpenKey *r)
368 {
369         struct dcesrv_handle *h, *newh;
370         WERROR result;
371
372         DCESRV_PULL_HANDLE_FAULT(h, r->in.parent_handle, HTYPE_REGKEY);
373
374         switch (security_session_user_level(dce_call->conn->auth_state.session_info))
375         {
376         case SECURITY_SYSTEM:
377         case SECURITY_ADMINISTRATOR:
378         case SECURITY_USER:
379                 if (r->in.keyname.name && strcmp(r->in.keyname.name, "") == 0) {
380                         newh = talloc_reference(dce_call->context, h);
381                         result = WERR_OK;
382                 } else {
383                         newh = dcesrv_handle_new(dce_call->context, HTYPE_REGKEY);
384                         result = reg_open_key(newh, (struct registry_key *)h->data,
385                                               r->in.keyname.name,
386                                               (struct registry_key **)&newh->data);
387                 }
388                 
389                 if (W_ERROR_IS_OK(result)) {
390                         r->out.handle = &newh->wire_handle;
391                 } else {
392                         talloc_free(newh);
393                 }
394                 return result;
395         default:
396                 return WERR_ACCESS_DENIED;
397         }
398
399 }
400
401
402 /*
403   winreg_QueryInfoKey
404 */
405 static WERROR dcesrv_winreg_QueryInfoKey(struct dcesrv_call_state *dce_call,
406                                          TALLOC_CTX *mem_ctx,
407                                          struct winreg_QueryInfoKey *r)
408 {
409         struct dcesrv_handle *h;
410         struct registry_key *k;
411         WERROR ret;
412         const char *classname = NULL;
413
414         DCESRV_PULL_HANDLE_FAULT(h, r->in.handle, HTYPE_REGKEY);
415
416         switch (security_session_user_level(dce_call->conn->auth_state.session_info))
417         {
418         case SECURITY_SYSTEM:
419         case SECURITY_ADMINISTRATOR:
420         case SECURITY_USER:
421                 k = h->data;
422                 
423                 ret = reg_key_get_info(mem_ctx, k, &classname, r->out.num_subkeys,
424                                        r->out.num_values, r->out.last_changed_time,
425                                        r->out.max_subkeylen, r->out.max_valnamelen, 
426                                        r->out.max_valbufsize);
427                 
428                 if (r->out.classname != NULL)
429                         r->out.classname->name = classname;
430                 
431                 return ret;
432         default:
433                 return WERR_ACCESS_DENIED;
434         }
435 }
436
437
438 /*
439   winreg_QueryValue
440 */
441 static WERROR dcesrv_winreg_QueryValue(struct dcesrv_call_state *dce_call,
442                                        TALLOC_CTX *mem_ctx,
443                                        struct winreg_QueryValue *r)
444 {
445         struct dcesrv_handle *h;
446         struct registry_key *key;
447         uint32_t value_type;
448         DATA_BLOB value_data;
449         WERROR result;
450
451         DCESRV_PULL_HANDLE_FAULT(h, r->in.handle, HTYPE_REGKEY);
452
453         switch (security_session_user_level(dce_call->conn->auth_state.session_info))
454         {
455         case SECURITY_SYSTEM:
456         case SECURITY_ADMINISTRATOR:
457         case SECURITY_USER:
458                 key = h->data;
459                 
460                 result = reg_key_get_value_by_name(mem_ctx, key, r->in.value_name->name,
461                                                    &value_type, &value_data);
462                 
463                 if (!W_ERROR_IS_OK(result)) {
464                         return result;
465                 }
466                 
467                 /* Just asking for the size of the buffer */
468                 r->out.type = talloc(mem_ctx, uint32_t);
469                 if (!r->out.type) {
470                         return WERR_NOMEM;
471                 }
472                 *r->out.type = value_type;
473                 r->out.data_length = talloc(mem_ctx, uint32_t);
474                 if (!r->out.data_length) {
475                         return WERR_NOMEM;
476                 }
477                 *r->out.data_length = value_data.length;
478                 if (r->in.data == NULL) {
479                         r->out.data_size = talloc(mem_ctx, uint32_t);
480                         *r->out.data_size = value_data.length;
481                 } else {
482                         r->out.data_size = r->in.data_size;
483                         r->out.data = value_data.data;
484                 }
485                 
486                 return WERR_OK;
487         default:
488                 return WERR_ACCESS_DENIED;
489         }
490 }
491
492
493 /*
494   winreg_ReplaceKey
495 */
496 static WERROR dcesrv_winreg_ReplaceKey(struct dcesrv_call_state *dce_call,
497                                        TALLOC_CTX *mem_ctx,
498                                        struct winreg_ReplaceKey *r)
499 {
500         return WERR_NOT_SUPPORTED;
501 }
502
503
504 /*
505   winreg_RestoreKey
506 */
507 static WERROR dcesrv_winreg_RestoreKey(struct dcesrv_call_state *dce_call,
508                                        TALLOC_CTX *mem_ctx,
509                                        struct winreg_RestoreKey *r)
510 {
511         return WERR_NOT_SUPPORTED;
512 }
513
514
515 /*
516   winreg_SaveKey
517 */
518 static WERROR dcesrv_winreg_SaveKey(struct dcesrv_call_state *dce_call,
519                                     TALLOC_CTX *mem_ctx,
520                                     struct winreg_SaveKey *r)
521 {
522         return WERR_NOT_SUPPORTED;
523 }
524
525
526 /*
527   winreg_SetKeySecurity
528 */
529 static WERROR dcesrv_winreg_SetKeySecurity(struct dcesrv_call_state *dce_call,
530                                            TALLOC_CTX *mem_ctx,
531                                            struct winreg_SetKeySecurity *r)
532 {
533         return WERR_NOT_SUPPORTED;
534 }
535
536
537 /*
538   winreg_SetValue
539 */
540 static WERROR dcesrv_winreg_SetValue(struct dcesrv_call_state *dce_call,
541                                      TALLOC_CTX *mem_ctx,
542                                      struct winreg_SetValue *r)
543 {
544         struct dcesrv_handle *h;
545         struct registry_key *key;
546         WERROR result;
547         DATA_BLOB data;
548
549         DCESRV_PULL_HANDLE_FAULT(h, r->in.handle, HTYPE_REGKEY);
550
551         key = h->data;
552
553         switch (security_session_user_level(dce_call->conn->auth_state.session_info))
554         {
555         case SECURITY_SYSTEM:
556         case SECURITY_ADMINISTRATOR:
557                 data.data = r->in.data;
558                 data.length = r->in.size;
559                 result = reg_val_set(key, r->in.name.name, r->in.type, data);
560                 return result;
561         default:
562                 return WERR_ACCESS_DENIED;
563         }
564 }
565
566
567 /*
568   winreg_UnLoadKey
569 */
570 static WERROR dcesrv_winreg_UnLoadKey(struct dcesrv_call_state *dce_call,
571                                       TALLOC_CTX *mem_ctx,
572                                       struct winreg_UnLoadKey *r)
573 {
574         return WERR_NOT_SUPPORTED;
575 }
576
577
578 /*
579   winreg_InitiateSystemShutdown
580 */
581 static WERROR dcesrv_winreg_InitiateSystemShutdown(struct dcesrv_call_state *dce_call,
582                                                    TALLOC_CTX *mem_ctx,
583                                                    struct winreg_InitiateSystemShutdown *r)
584 {
585         return WERR_NOT_SUPPORTED;
586 }
587
588
589 /*
590   winreg_AbortSystemShutdown
591 */
592 static WERROR dcesrv_winreg_AbortSystemShutdown(struct dcesrv_call_state *dce_call,
593                                                 TALLOC_CTX *mem_ctx,
594                                                 struct winreg_AbortSystemShutdown *r)
595 {
596         return WERR_NOT_SUPPORTED;
597 }
598
599
600 /*
601   winreg_GetVersion
602 */
603 static WERROR dcesrv_winreg_GetVersion(struct dcesrv_call_state *dce_call,
604                                        TALLOC_CTX *mem_ctx,
605                                        struct winreg_GetVersion *r)
606 {
607         struct dcesrv_handle *h;
608
609         DCESRV_PULL_HANDLE_FAULT(h, r->in.handle, HTYPE_REGKEY);
610
611         r->out.version = talloc(mem_ctx, uint32_t);
612         W_ERROR_HAVE_NO_MEMORY(r->out.version);
613
614         *r->out.version = 5;
615
616         return WERR_OK;
617 }
618
619
620 /*
621   winreg_QueryMultipleValues
622 */
623 static WERROR dcesrv_winreg_QueryMultipleValues(struct dcesrv_call_state *dce_call,
624                                                 TALLOC_CTX *mem_ctx,
625                                                 struct winreg_QueryMultipleValues *r)
626 {
627         return WERR_NOT_SUPPORTED;
628 }
629
630
631 /*
632   winreg_InitiateSystemShutdownEx
633 */
634 static WERROR dcesrv_winreg_InitiateSystemShutdownEx(struct dcesrv_call_state *dce_call,
635                                                      TALLOC_CTX *mem_ctx,
636                                                      struct winreg_InitiateSystemShutdownEx *r)
637 {
638         return WERR_NOT_SUPPORTED;
639 }
640
641
642 /*
643   winreg_SaveKeyEx
644 */
645 static WERROR dcesrv_winreg_SaveKeyEx(struct dcesrv_call_state *dce_call,
646                                       TALLOC_CTX *mem_ctx,
647                                       struct winreg_SaveKeyEx *r)
648 {
649         return WERR_NOT_SUPPORTED;
650 }
651
652
653 /*
654   winreg_QueryMultipleValues2
655 */
656 static WERROR dcesrv_winreg_QueryMultipleValues2(struct dcesrv_call_state *dce_call,
657                                                  TALLOC_CTX *mem_ctx,
658                                                  struct winreg_QueryMultipleValues2 *r)
659 {
660         return WERR_NOT_SUPPORTED;
661 }
662
663
664 /* include the generated boilerplate */
665 #include "librpc/gen_ndr/ndr_winreg_s.c"