~zulcss/samba/server-dailies-3.4

« back to all changes in this revision

Viewing changes to source4/rpc_server/winreg/rpc_winreg.c

  • Committer: Chuck Short
  • Date: 2010-09-28 20:38:39 UTC
  • Revision ID: zulcss@ubuntu.com-20100928203839-pgjulytsi9ue63x1
Initial version

Show diffs side-by-side

added added

removed removed

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