~lefteris-nikoltsios/+junk/samba-lp1016895

« back to all changes in this revision

Viewing changes to source3/rpc_server/winreg/srv_winreg_nt.c

  • Committer: Package Import Robot
  • Author(s): Chuck Short
  • Date: 2011-12-21 13:18:04 UTC
  • mfrom: (0.39.21 sid)
  • Revision ID: package-import@ubuntu.com-20111221131804-xtlr39wx6njehxxr
Tags: 2:3.6.1-3ubuntu1
* Merge from Debian testing.  Remaining changes:
  + debian/patches/VERSION.patch:
    - set SAMBA_VERSION_SUFFIX to Ubuntu.
  + debian/patches/error-trans.fix-276472:
    - Add the translation of Unix Error code -ENOTSUP to NT Error Code
    - NT_STATUS_NOT_SUPPORTED to prevent the Permission denied error.
  + debian/smb.conf:
    - add "(Samba, Ubuntu)" to server string.
    - comment out the default [homes] share, and add a comment about
      "valid users = %S" to show users how to restrict access to
      \\server\username to only username.
    - Set 'usershare allow guests', so that usershare admins are 
      allowed to create public shares in addition to authenticated
      ones.
    - add map to guest = Bad user, maps bad username to guest access.
  + debian/samba-common.config:
    - Do not change priority to high if dhclient3 is installed.
    - Use priority medium instead of high for the workgroup question.
  + debian/control:
    - Don't build against or suggest ctdb.
    - Add dependency on samba-common-bin to samba.
  + Add ufw integration:
    - Created debian/samba.ufw.profile
    - debian/rules, debian/samba.dirs, debian/samba.files: install
      profile
    - debian/control: have samba suggest ufw
  + Add apport hook:
    - Created debian/source_samba.py.
    - debian/rules, debian/samba.dirs, debian/samba-common-bin.files: install
  + Switch to upstart:
    - Add debian/samba.{nmbd,smbd}.upstart.
  + debian/samba.logrotate, debian/samba-common.dhcp, debian/samba.if-up:
    - Make them upstart compatible
  + debian/samba.postinst: 
    - Avoid scary pdbedit warnings on first import.
  + debian/samba-common.postinst: Add more informative error message for
    the case where smb.conf was manually deleted
  + debian/patches/fix-debuglevel-name-conflict.patch: don't use 'debug_level'
    as a global variable name in an NSS module 
  + Dropped:
    - debian/patches/error-trans.fix-276472
    - debian/patches/fix-debuglevel-name-conflict.patch

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *  Unix SMB/CIFS implementation.
 
3
 *  RPC Pipe client / server routines
 
4
 *
 
5
 *  Copyright (C) Gerald Carter                 2002-2006.
 
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 functions. */
 
22
 
 
23
#include "includes.h"
 
24
#include "ntdomain.h"
 
25
#include "../librpc/gen_ndr/srv_winreg.h"
 
26
#include "registry.h"
 
27
#include "registry/reg_api.h"
 
28
#include "registry/reg_api_regf.h"
 
29
#include "registry/reg_perfcount.h"
 
30
#include "rpc_misc.h"
 
31
#include "auth.h"
 
32
#include "lib/privileges.h"
 
33
 
 
34
#undef DBGC_CLASS
 
35
#define DBGC_CLASS DBGC_RPC_SRV
 
36
 
 
37
/******************************************************************
 
38
 Find a registry key handle and return a struct registry_key *
 
39
 *****************************************************************/
 
40
 
 
41
static struct registry_key *find_regkey_by_hnd(struct pipes_struct *p,
 
42
                                               struct policy_handle *hnd)
 
43
{
 
44
        struct registry_key *regkey = NULL;
 
45
 
 
46
        if(!find_policy_by_hnd(p,hnd,(void **)(void *)&regkey)) {
 
47
                DEBUG(2,("find_regkey_index_by_hnd: Registry Key not found: "));
 
48
                return NULL;
 
49
        }
 
50
 
 
51
        return regkey;
 
52
}
 
53
 
 
54
/*******************************************************************
 
55
 Function for open a new registry handle and creating a handle
 
56
 Note that P should be valid & hnd should already have space
 
57
 
 
58
 When we open a key, we store the full path to the key as
 
59
 HK[LM|U]\<key>\<key>\...
 
60
 *******************************************************************/
 
61
 
 
62
static WERROR open_registry_key(struct pipes_struct *p,
 
63
                                struct policy_handle *hnd,
 
64
                                struct registry_key *parent,
 
65
                                const char *subkeyname,
 
66
                                uint32_t access_desired)
 
67
{
 
68
        WERROR result = WERR_OK;
 
69
        struct registry_key *key;
 
70
 
 
71
        if (parent == NULL) {
 
72
                result = reg_openhive(p->mem_ctx, subkeyname, access_desired,
 
73
                                      p->session_info->security_token, &key);
 
74
        }
 
75
        else {
 
76
                result = reg_openkey(p->mem_ctx, parent, subkeyname,
 
77
                                     access_desired, &key);
 
78
        }
 
79
 
 
80
        if ( !W_ERROR_IS_OK(result) ) {
 
81
                return result;
 
82
        }
 
83
 
 
84
        if ( !create_policy_hnd( p, hnd, key ) ) {
 
85
                return WERR_BADFILE;
 
86
        }
 
87
 
 
88
        return WERR_OK;
 
89
}
 
90
 
 
91
/*******************************************************************
 
92
 Function for open a new registry handle and creating a handle
 
93
 Note that P should be valid & hnd should already have space
 
94
 *******************************************************************/
 
95
 
 
96
static bool close_registry_key(struct pipes_struct *p,
 
97
                               struct policy_handle *hnd)
 
98
{
 
99
        struct registry_key *regkey = find_regkey_by_hnd(p, hnd);
 
100
 
 
101
        if ( !regkey ) {
 
102
                DEBUG(2,("close_registry_key: Invalid handle (%s:%u:%u)\n",
 
103
                         OUR_HANDLE(hnd)));
 
104
                return False;
 
105
        }
 
106
 
 
107
        close_policy_hnd(p, hnd);
 
108
 
 
109
        return True;
 
110
}
 
111
 
 
112
/********************************************************************
 
113
 _winreg_CloseKey
 
114
 ********************************************************************/
 
115
 
 
116
WERROR _winreg_CloseKey(struct pipes_struct *p,
 
117
                        struct winreg_CloseKey *r)
 
118
{
 
119
        /* close the policy handle */
 
120
 
 
121
        if (!close_registry_key(p, r->in.handle))
 
122
                return WERR_BADFID;
 
123
 
 
124
        ZERO_STRUCTP(r->out.handle);
 
125
 
 
126
        return WERR_OK;
 
127
}
 
128
 
 
129
/*******************************************************************
 
130
 _winreg_OpenHKLM
 
131
 ********************************************************************/
 
132
 
 
133
WERROR _winreg_OpenHKLM(struct pipes_struct *p,
 
134
                        struct winreg_OpenHKLM *r)
 
135
{
 
136
        return open_registry_key(p, r->out.handle, NULL, KEY_HKLM, r->in.access_mask);
 
137
}
 
138
 
 
139
/*******************************************************************
 
140
 _winreg_OpenHKPD
 
141
 ********************************************************************/
 
142
 
 
143
WERROR _winreg_OpenHKPD(struct pipes_struct *p,
 
144
                        struct winreg_OpenHKPD *r)
 
145
{
 
146
        return open_registry_key(p, r->out.handle, NULL, KEY_HKPD, r->in.access_mask);
 
147
}
 
148
 
 
149
/*******************************************************************
 
150
 _winreg_OpenHKPT
 
151
 ********************************************************************/
 
152
 
 
153
WERROR _winreg_OpenHKPT(struct pipes_struct *p,
 
154
                        struct winreg_OpenHKPT *r)
 
155
{
 
156
        return open_registry_key(p, r->out.handle, NULL, KEY_HKPT, r->in.access_mask);
 
157
}
 
158
 
 
159
/*******************************************************************
 
160
 _winreg_OpenHKCR
 
161
 ********************************************************************/
 
162
 
 
163
WERROR _winreg_OpenHKCR(struct pipes_struct *p,
 
164
                        struct winreg_OpenHKCR *r)
 
165
{
 
166
        return open_registry_key(p, r->out.handle, NULL, KEY_HKCR, r->in.access_mask);
 
167
}
 
168
 
 
169
/*******************************************************************
 
170
 _winreg_OpenHKU
 
171
 ********************************************************************/
 
172
 
 
173
WERROR _winreg_OpenHKU(struct pipes_struct *p,
 
174
                       struct winreg_OpenHKU *r)
 
175
{
 
176
        return open_registry_key(p, r->out.handle, NULL, KEY_HKU, r->in.access_mask);
 
177
}
 
178
 
 
179
/*******************************************************************
 
180
 _winreg_OpenHKCU
 
181
 ********************************************************************/
 
182
 
 
183
WERROR _winreg_OpenHKCU(struct pipes_struct *p,
 
184
                        struct winreg_OpenHKCU *r)
 
185
{
 
186
        return open_registry_key(p, r->out.handle, NULL, KEY_HKCU, r->in.access_mask);
 
187
}
 
188
 
 
189
/*******************************************************************
 
190
 _winreg_OpenHKCC
 
191
 ********************************************************************/
 
192
 
 
193
WERROR _winreg_OpenHKCC(struct pipes_struct *p,
 
194
                        struct winreg_OpenHKCC *r)
 
195
{
 
196
        return open_registry_key(p, r->out.handle, NULL, KEY_HKCC, r->in.access_mask);
 
197
}
 
198
 
 
199
/*******************************************************************
 
200
 _winreg_OpenHKDD
 
201
 ********************************************************************/
 
202
 
 
203
WERROR _winreg_OpenHKDD(struct pipes_struct *p,
 
204
                        struct winreg_OpenHKDD *r)
 
205
{
 
206
        return open_registry_key(p, r->out.handle, NULL, KEY_HKDD, r->in.access_mask);
 
207
}
 
208
 
 
209
/*******************************************************************
 
210
 _winreg_OpenHKPN
 
211
 ********************************************************************/
 
212
 
 
213
WERROR _winreg_OpenHKPN(struct pipes_struct *p,
 
214
                        struct winreg_OpenHKPN *r)
 
215
{
 
216
        return open_registry_key(p, r->out.handle, NULL, KEY_HKPN, r->in.access_mask);
 
217
}
 
218
 
 
219
/*******************************************************************
 
220
 _winreg_OpenKey
 
221
 ********************************************************************/
 
222
 
 
223
WERROR _winreg_OpenKey(struct pipes_struct *p,
 
224
                       struct winreg_OpenKey *r)
 
225
{
 
226
        struct registry_key *parent = find_regkey_by_hnd(p, r->in.parent_handle );
 
227
 
 
228
        if ( !parent )
 
229
                return WERR_BADFID;
 
230
 
 
231
        return open_registry_key(p, r->out.handle, parent, r->in.keyname.name, r->in.access_mask);
 
232
}
 
233
 
 
234
/*******************************************************************
 
235
 _winreg_QueryValue
 
236
 ********************************************************************/
 
237
 
 
238
WERROR _winreg_QueryValue(struct pipes_struct *p,
 
239
                          struct winreg_QueryValue *r)
 
240
{
 
241
        WERROR        status = WERR_BADFILE;
 
242
        struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
 
243
        prs_struct    prs_hkpd;
 
244
 
 
245
        uint8_t *outbuf = NULL;
 
246
        uint32_t outbuf_size = 0;
 
247
 
 
248
        bool free_buf = False;
 
249
        bool free_prs = False;
 
250
 
 
251
        if ( !regkey )
 
252
                return WERR_BADFID;
 
253
 
 
254
        if (r->in.value_name->name == NULL) {
 
255
                return WERR_INVALID_PARAM;
 
256
        }
 
257
 
 
258
        if ((r->out.data_length == NULL) || (r->out.type == NULL) || (r->out.data_size == NULL)) {
 
259
                return WERR_INVALID_PARAM;
 
260
        }
 
261
 
 
262
        DEBUG(7,("_winreg_QueryValue: policy key name = [%s]\n", regkey->key->name));
 
263
        DEBUG(7,("_winreg_QueryValue: policy key type = [%08x]\n", regkey->key->type));
 
264
 
 
265
        /* Handle QueryValue calls on HKEY_PERFORMANCE_DATA */
 
266
        if(regkey->key->type == REG_KEY_HKPD)
 
267
        {
 
268
                if (strequal(r->in.value_name->name, "Global")) {
 
269
                        if (!prs_init(&prs_hkpd, *r->in.data_size, p->mem_ctx, MARSHALL))
 
270
                                return WERR_NOMEM;
 
271
                        status = reg_perfcount_get_hkpd(
 
272
                                &prs_hkpd, *r->in.data_size, &outbuf_size, NULL);
 
273
                        outbuf = (uint8_t *)prs_hkpd.data_p;
 
274
                        free_prs = True;
 
275
                }
 
276
                else if (strequal(r->in.value_name->name, "Counter 009")) {
 
277
                        outbuf_size = reg_perfcount_get_counter_names(
 
278
                                reg_perfcount_get_base_index(),
 
279
                                (char **)(void *)&outbuf);
 
280
                        free_buf = True;
 
281
                }
 
282
                else if (strequal(r->in.value_name->name, "Explain 009")) {
 
283
                        outbuf_size = reg_perfcount_get_counter_help(
 
284
                                reg_perfcount_get_base_index(),
 
285
                                (char **)(void *)&outbuf);
 
286
                        free_buf = True;
 
287
                }
 
288
                else if (isdigit(r->in.value_name->name[0])) {
 
289
                        /* we probably have a request for a specific object
 
290
                         * here */
 
291
                        if (!prs_init(&prs_hkpd, *r->in.data_size, p->mem_ctx, MARSHALL))
 
292
                                return WERR_NOMEM;
 
293
                        status = reg_perfcount_get_hkpd(
 
294
                                &prs_hkpd, *r->in.data_size, &outbuf_size,
 
295
                                r->in.value_name->name);
 
296
                        outbuf = (uint8_t *)prs_hkpd.data_p;
 
297
                        free_prs = True;
 
298
                }
 
299
                else {
 
300
                        DEBUG(3,("Unsupported key name [%s] for HKPD.\n",
 
301
                                 r->in.value_name->name));
 
302
                        return WERR_BADFILE;
 
303
                }
 
304
 
 
305
                *r->out.type = REG_BINARY;
 
306
        }
 
307
        else {
 
308
                struct registry_value *val;
 
309
 
 
310
                status = reg_queryvalue(p->mem_ctx, regkey, r->in.value_name->name,
 
311
                                        &val);
 
312
                if (!W_ERROR_IS_OK(status)) {
 
313
 
 
314
                        DEBUG(10,("_winreg_QueryValue: reg_queryvalue failed with: %s\n",
 
315
                                win_errstr(status)));
 
316
 
 
317
                        if (r->out.data_size) {
 
318
                                *r->out.data_size = 0;
 
319
                        }
 
320
                        if (r->out.data_length) {
 
321
                                *r->out.data_length = 0;
 
322
                        }
 
323
                        return status;
 
324
                }
 
325
 
 
326
                outbuf = val->data.data;
 
327
                outbuf_size = val->data.length;
 
328
                *r->out.type = val->type;
 
329
        }
 
330
 
 
331
        status = WERR_BADFILE;
 
332
 
 
333
        if (*r->in.data_size < outbuf_size) {
 
334
                *r->out.data_size = outbuf_size;
 
335
                status = r->in.data ? WERR_MORE_DATA : WERR_OK;
 
336
        } else {
 
337
                *r->out.data_length = outbuf_size;
 
338
                *r->out.data_size = outbuf_size;
 
339
                if (r->out.data) {
 
340
                        memcpy(r->out.data, outbuf, outbuf_size);
 
341
                }
 
342
                status = WERR_OK;
 
343
        }
 
344
 
 
345
        if (free_prs) prs_mem_free(&prs_hkpd);
 
346
        if (free_buf) SAFE_FREE(outbuf);
 
347
 
 
348
        return status;
 
349
}
 
350
 
 
351
/*****************************************************************************
 
352
 _winreg_QueryInfoKey
 
353
 ****************************************************************************/
 
354
 
 
355
WERROR _winreg_QueryInfoKey(struct pipes_struct *p,
 
356
                            struct winreg_QueryInfoKey *r)
 
357
{
 
358
        WERROR  status = WERR_OK;
 
359
        struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
 
360
 
 
361
        if ( !regkey )
 
362
                return WERR_BADFID;
 
363
 
 
364
        r->out.classname->name = NULL;
 
365
 
 
366
        status = reg_queryinfokey(regkey, r->out.num_subkeys, r->out.max_subkeylen,
 
367
                                  r->out.max_classlen, r->out.num_values, r->out.max_valnamelen,
 
368
                                  r->out.max_valbufsize, r->out.secdescsize,
 
369
                                  r->out.last_changed_time);
 
370
        if (!W_ERROR_IS_OK(status)) {
 
371
                return status;
 
372
        }
 
373
 
 
374
        /*
 
375
         * These calculations account for the registry buffers being
 
376
         * UTF-16. They are inexact at best, but so far they worked.
 
377
         */
 
378
 
 
379
        *r->out.max_subkeylen *= 2;
 
380
 
 
381
        *r->out.max_valnamelen += 1;
 
382
        *r->out.max_valnamelen *= 2;
 
383
 
 
384
        return WERR_OK;
 
385
}
 
386
 
 
387
 
 
388
/*****************************************************************************
 
389
 _winreg_GetVersion
 
390
 ****************************************************************************/
 
391
 
 
392
WERROR _winreg_GetVersion(struct pipes_struct *p,
 
393
                          struct winreg_GetVersion *r)
 
394
{
 
395
        struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
 
396
 
 
397
        if ( !regkey )
 
398
                return WERR_BADFID;
 
399
 
 
400
        return reg_getversion(r->out.version);
 
401
}
 
402
 
 
403
 
 
404
/*****************************************************************************
 
405
 _winreg_EnumKey
 
406
 ****************************************************************************/
 
407
 
 
408
WERROR _winreg_EnumKey(struct pipes_struct *p,
 
409
                       struct winreg_EnumKey *r)
 
410
{
 
411
        WERROR err = WERR_OK;
 
412
        struct registry_key *key = find_regkey_by_hnd( p, r->in.handle );
 
413
 
 
414
        if ( !key )
 
415
                return WERR_BADFID;
 
416
 
 
417
        if ( !r->in.name || !r->in.keyclass )
 
418
                return WERR_INVALID_PARAM;
 
419
 
 
420
        DEBUG(8,("_winreg_EnumKey: enumerating key [%s]\n", key->key->name));
 
421
 
 
422
        err = reg_enumkey(p->mem_ctx, key, r->in.enum_index, (char **)&r->out.name->name,
 
423
                          r->out.last_changed_time);
 
424
        if (!W_ERROR_IS_OK(err)) {
 
425
                return err;
 
426
        }
 
427
        r->out.keyclass->name = "";
 
428
        return WERR_OK;
 
429
}
 
430
 
 
431
/*****************************************************************************
 
432
 _winreg_EnumValue
 
433
 ****************************************************************************/
 
434
 
 
435
WERROR _winreg_EnumValue(struct pipes_struct *p,
 
436
                         struct winreg_EnumValue *r)
 
437
{
 
438
        WERROR err = WERR_OK;
 
439
        struct registry_key *key = find_regkey_by_hnd( p, r->in.handle );
 
440
        char *valname = NULL;
 
441
        struct registry_value *val = NULL;
 
442
 
 
443
        if ( !key )
 
444
                return WERR_BADFID;
 
445
 
 
446
        if ( !r->in.name )
 
447
                return WERR_INVALID_PARAM;
 
448
 
 
449
        DEBUG(8,("_winreg_EnumValue: enumerating values for key [%s]\n",
 
450
                 key->key->name));
 
451
 
 
452
        err = reg_enumvalue(p->mem_ctx, key, r->in.enum_index, &valname, &val);
 
453
        if (!W_ERROR_IS_OK(err)) {
 
454
                return err;
 
455
        }
 
456
 
 
457
        if (r->out.name != NULL) {
 
458
                r->out.name->name = valname;
 
459
        }
 
460
 
 
461
        if (r->out.type != NULL) {
 
462
                *r->out.type = val->type;
 
463
        }
 
464
 
 
465
        if (r->out.value != NULL) {
 
466
                if ((r->out.size == NULL) || (r->out.length == NULL)) {
 
467
                        return WERR_INVALID_PARAM;
 
468
                }
 
469
 
 
470
                if (val->data.length > *r->out.size) {
 
471
                        return WERR_MORE_DATA;
 
472
                }
 
473
 
 
474
                memcpy( r->out.value, val->data.data, val->data.length );
 
475
        }
 
476
 
 
477
        if (r->out.length != NULL) {
 
478
                *r->out.length = val->data.length;
 
479
        }
 
480
        if (r->out.size != NULL) {
 
481
                *r->out.size = val->data.length;
 
482
        }
 
483
 
 
484
        return WERR_OK;
 
485
}
 
486
 
 
487
/*******************************************************************
 
488
 _winreg_InitiateSystemShutdown
 
489
 ********************************************************************/
 
490
 
 
491
WERROR _winreg_InitiateSystemShutdown(struct pipes_struct *p,
 
492
                                      struct winreg_InitiateSystemShutdown *r)
 
493
{
 
494
        struct winreg_InitiateSystemShutdownEx s;
 
495
 
 
496
        s.in.hostname = r->in.hostname;
 
497
        s.in.message = r->in.message;
 
498
        s.in.timeout = r->in.timeout;
 
499
        s.in.force_apps = r->in.force_apps;
 
500
        s.in.do_reboot = r->in.do_reboot;
 
501
        s.in.reason = 0;
 
502
 
 
503
        /* thunk down to _winreg_InitiateSystemShutdownEx()
 
504
           (just returns a status) */
 
505
 
 
506
        return _winreg_InitiateSystemShutdownEx( p, &s );
 
507
}
 
508
 
 
509
/*******************************************************************
 
510
 _winreg_InitiateSystemShutdownEx
 
511
 ********************************************************************/
 
512
 
 
513
#define SHUTDOWN_R_STRING "-r"
 
514
#define SHUTDOWN_F_STRING "-f"
 
515
 
 
516
 
 
517
WERROR _winreg_InitiateSystemShutdownEx(struct pipes_struct *p,
 
518
                                        struct winreg_InitiateSystemShutdownEx *r)
 
519
{
 
520
        char *shutdown_script = NULL;
 
521
        char *msg = NULL;
 
522
        char *chkmsg = NULL;
 
523
        fstring str_timeout;
 
524
        fstring str_reason;
 
525
        fstring do_reboot;
 
526
        fstring f;
 
527
        int ret = -1;
 
528
        bool can_shutdown = false;
 
529
 
 
530
        shutdown_script = talloc_strdup(p->mem_ctx, lp_shutdown_script());
 
531
        if (!shutdown_script) {
 
532
                return WERR_NOMEM;
 
533
        }
 
534
        if (!*shutdown_script) {
 
535
                return WERR_ACCESS_DENIED;
 
536
        }
 
537
 
 
538
        /* pull the message string and perform necessary sanity checks on it */
 
539
 
 
540
        if ( r->in.message && r->in.message->string ) {
 
541
                if ( (msg = talloc_strdup(p->mem_ctx, r->in.message->string )) == NULL ) {
 
542
                        return WERR_NOMEM;
 
543
                }
 
544
                chkmsg = TALLOC_ARRAY(p->mem_ctx, char, strlen(msg)+1);
 
545
                if (!chkmsg) {
 
546
                        return WERR_NOMEM;
 
547
                }
 
548
                alpha_strcpy(chkmsg, msg, NULL, strlen(msg)+1);
 
549
        }
 
550
 
 
551
        fstr_sprintf(str_timeout, "%d", r->in.timeout);
 
552
        fstr_sprintf(do_reboot, r->in.do_reboot ? SHUTDOWN_R_STRING : "");
 
553
        fstr_sprintf(f, r->in.force_apps ? SHUTDOWN_F_STRING : "");
 
554
        fstr_sprintf(str_reason, "%d", r->in.reason );
 
555
 
 
556
        shutdown_script = talloc_all_string_sub(p->mem_ctx,
 
557
                                shutdown_script, "%z", chkmsg ? chkmsg : "");
 
558
        if (!shutdown_script) {
 
559
                return WERR_NOMEM;
 
560
        }
 
561
        shutdown_script = talloc_all_string_sub(p->mem_ctx,
 
562
                                        shutdown_script, "%t", str_timeout);
 
563
        if (!shutdown_script) {
 
564
                return WERR_NOMEM;
 
565
        }
 
566
        shutdown_script = talloc_all_string_sub(p->mem_ctx,
 
567
                                                shutdown_script, "%r", do_reboot);
 
568
        if (!shutdown_script) {
 
569
                return WERR_NOMEM;
 
570
        }
 
571
        shutdown_script = talloc_all_string_sub(p->mem_ctx,
 
572
                                                shutdown_script, "%f", f);
 
573
        if (!shutdown_script) {
 
574
                return WERR_NOMEM;
 
575
        }
 
576
        shutdown_script = talloc_all_string_sub(p->mem_ctx,
 
577
                                        shutdown_script, "%x", str_reason);
 
578
        if (!shutdown_script) {
 
579
                return WERR_NOMEM;
 
580
        }
 
581
 
 
582
        can_shutdown = security_token_has_privilege(p->session_info->security_token, SEC_PRIV_REMOTE_SHUTDOWN);
 
583
 
 
584
        /* IF someone has privs, run the shutdown script as root. OTHERWISE run it as not root
 
585
           Take the error return from the script and provide it as the Windows return code. */
 
586
 
 
587
        /********** BEGIN SeRemoteShutdownPrivilege BLOCK **********/
 
588
 
 
589
        if ( can_shutdown )
 
590
                become_root();
 
591
 
 
592
        ret = smbrun( shutdown_script, NULL );
 
593
 
 
594
        if ( can_shutdown )
 
595
                unbecome_root();
 
596
 
 
597
        /********** END SeRemoteShutdownPrivilege BLOCK **********/
 
598
 
 
599
        DEBUG(3,("_reg_shutdown_ex: Running the command `%s' gave %d\n",
 
600
                shutdown_script, ret));
 
601
 
 
602
        return (ret == 0) ? WERR_OK : WERR_ACCESS_DENIED;
 
603
}
 
604
 
 
605
/*******************************************************************
 
606
 _winreg_AbortSystemShutdown
 
607
 ********************************************************************/
 
608
 
 
609
WERROR _winreg_AbortSystemShutdown(struct pipes_struct *p,
 
610
                                   struct winreg_AbortSystemShutdown *r)
 
611
{
 
612
        const char *abort_shutdown_script = lp_abort_shutdown_script();
 
613
        int ret = -1;
 
614
        bool can_shutdown = false;
 
615
 
 
616
        if (!*abort_shutdown_script)
 
617
                return WERR_ACCESS_DENIED;
 
618
 
 
619
        can_shutdown = security_token_has_privilege(p->session_info->security_token, SEC_PRIV_REMOTE_SHUTDOWN);
 
620
 
 
621
        /********** BEGIN SeRemoteShutdownPrivilege BLOCK **********/
 
622
 
 
623
        if ( can_shutdown )
 
624
                become_root();
 
625
 
 
626
        ret = smbrun( abort_shutdown_script, NULL );
 
627
 
 
628
        if ( can_shutdown )
 
629
                unbecome_root();
 
630
 
 
631
        /********** END SeRemoteShutdownPrivilege BLOCK **********/
 
632
 
 
633
        DEBUG(3,("_winreg_AbortSystemShutdown: Running the command `%s' gave %d\n",
 
634
                abort_shutdown_script, ret));
 
635
 
 
636
        return (ret == 0) ? WERR_OK : WERR_ACCESS_DENIED;
 
637
}
 
638
 
 
639
/*******************************************************************
 
640
 ********************************************************************/
 
641
 
 
642
static int validate_reg_filename(TALLOC_CTX *ctx, char **pp_fname )
 
643
{
 
644
        char *p = NULL;
 
645
        int num_services = lp_numservices();
 
646
        int snum = -1;
 
647
        const char *share_path = NULL;
 
648
        char *fname = *pp_fname;
 
649
 
 
650
        /* convert to a unix path, stripping the C:\ along the way */
 
651
 
 
652
        if (!(p = valid_share_pathname(ctx, fname))) {
 
653
                return -1;
 
654
        }
 
655
 
 
656
        /* has to exist within a valid file share */
 
657
 
 
658
        for (snum=0; snum<num_services; snum++) {
 
659
                if (!lp_snum_ok(snum) || lp_print_ok(snum)) {
 
660
                        continue;
 
661
                }
 
662
 
 
663
                share_path = lp_pathname(snum);
 
664
 
 
665
                /* make sure we have a path (e.g. [homes] ) */
 
666
                if (strlen(share_path) == 0) {
 
667
                        continue;
 
668
                }
 
669
 
 
670
                if (strncmp(share_path, p, strlen(share_path)) == 0) {
 
671
                        break;
 
672
                }
 
673
        }
 
674
 
 
675
        *pp_fname = p;
 
676
        return (snum < num_services) ? snum : -1;
 
677
}
 
678
 
 
679
/*******************************************************************
 
680
 _winreg_RestoreKey
 
681
 ********************************************************************/
 
682
 
 
683
WERROR _winreg_RestoreKey(struct pipes_struct *p,
 
684
                          struct winreg_RestoreKey *r)
 
685
{
 
686
        struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
 
687
        char *fname = NULL;
 
688
        int snum = -1;
 
689
 
 
690
        if ( !regkey )
 
691
                return WERR_BADFID;
 
692
 
 
693
        if ( !r->in.filename || !r->in.filename->name )
 
694
                return WERR_INVALID_PARAM;
 
695
 
 
696
        fname = talloc_strdup(p->mem_ctx, r->in.filename->name);
 
697
        if (!fname) {
 
698
                return WERR_NOMEM;
 
699
        }
 
700
 
 
701
        DEBUG(8,("_winreg_RestoreKey: verifying restore of key [%s] from "
 
702
                 "\"%s\"\n", regkey->key->name, fname));
 
703
 
 
704
        if ((snum = validate_reg_filename(p->mem_ctx, &fname)) == -1)
 
705
                return WERR_OBJECT_PATH_INVALID;
 
706
 
 
707
        /* user must posses SeRestorePrivilege for this this proceed */
 
708
 
 
709
        if ( !security_token_has_privilege(p->session_info->security_token, SEC_PRIV_RESTORE)) {
 
710
                return WERR_ACCESS_DENIED;
 
711
        }
 
712
 
 
713
        DEBUG(2,("_winreg_RestoreKey: Restoring [%s] from %s in share %s\n",
 
714
                 regkey->key->name, fname, lp_servicename(snum) ));
 
715
 
 
716
        return reg_restorekey(regkey, fname);
 
717
}
 
718
 
 
719
/*******************************************************************
 
720
 _winreg_SaveKey
 
721
 ********************************************************************/
 
722
 
 
723
WERROR _winreg_SaveKey(struct pipes_struct *p,
 
724
                       struct winreg_SaveKey *r)
 
725
{
 
726
        struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
 
727
        char *fname = NULL;
 
728
        int snum = -1;
 
729
 
 
730
        if ( !regkey )
 
731
                return WERR_BADFID;
 
732
 
 
733
        if ( !r->in.filename || !r->in.filename->name )
 
734
                return WERR_INVALID_PARAM;
 
735
 
 
736
        fname = talloc_strdup(p->mem_ctx, r->in.filename->name);
 
737
        if (!fname) {
 
738
                return WERR_NOMEM;
 
739
        }
 
740
 
 
741
        DEBUG(8,("_winreg_SaveKey: verifying backup of key [%s] to \"%s\"\n",
 
742
                 regkey->key->name, fname));
 
743
 
 
744
        if ((snum = validate_reg_filename(p->mem_ctx, &fname)) == -1 )
 
745
                return WERR_OBJECT_PATH_INVALID;
 
746
 
 
747
        DEBUG(2,("_winreg_SaveKey: Saving [%s] to %s in share %s\n",
 
748
                 regkey->key->name, fname, lp_servicename(snum) ));
 
749
 
 
750
        return reg_savekey(regkey, fname);
 
751
}
 
752
 
 
753
/*******************************************************************
 
754
 _winreg_SaveKeyEx
 
755
 ********************************************************************/
 
756
 
 
757
WERROR _winreg_SaveKeyEx(struct pipes_struct *p,
 
758
                         struct winreg_SaveKeyEx *r)
 
759
{
 
760
        /* fill in your code here if you think this call should
 
761
           do anything */
 
762
 
 
763
        p->rng_fault_state = True;
 
764
        return WERR_NOT_SUPPORTED;
 
765
}
 
766
 
 
767
/*******************************************************************
 
768
 _winreg_CreateKey
 
769
 ********************************************************************/
 
770
 
 
771
WERROR _winreg_CreateKey(struct pipes_struct *p,
 
772
                         struct winreg_CreateKey *r)
 
773
{
 
774
        struct registry_key *parent = find_regkey_by_hnd(p, r->in.handle);
 
775
        struct registry_key *new_key = NULL;
 
776
        WERROR result = WERR_OK;
 
777
 
 
778
        if ( !parent )
 
779
                return WERR_BADFID;
 
780
 
 
781
        DEBUG(10, ("_winreg_CreateKey called with parent key '%s' and "
 
782
                   "subkey name '%s'\n", parent->key->name, r->in.name.name));
 
783
 
 
784
        result = reg_createkey(NULL, parent, r->in.name.name, r->in.access_mask,
 
785
                               &new_key, r->out.action_taken);
 
786
        if (!W_ERROR_IS_OK(result)) {
 
787
                return result;
 
788
        }
 
789
 
 
790
        if (!create_policy_hnd(p, r->out.new_handle, new_key)) {
 
791
                TALLOC_FREE(new_key);
 
792
                return WERR_BADFILE;
 
793
        }
 
794
 
 
795
        return WERR_OK;
 
796
}
 
797
 
 
798
/*******************************************************************
 
799
 _winreg_SetValue
 
800
 ********************************************************************/
 
801
 
 
802
WERROR _winreg_SetValue(struct pipes_struct *p,
 
803
                        struct winreg_SetValue *r)
 
804
{
 
805
        struct registry_key *key = find_regkey_by_hnd(p, r->in.handle);
 
806
        struct registry_value *val = NULL;
 
807
 
 
808
        if ( !key )
 
809
                return WERR_BADFID;
 
810
 
 
811
        DEBUG(8,("_winreg_SetValue: Setting value for [%s:%s]\n",
 
812
                         key->key->name, r->in.name.name));
 
813
 
 
814
        val = talloc_zero(p->mem_ctx, struct registry_value);
 
815
        if (val == NULL) {
 
816
                return WERR_NOMEM;
 
817
        }
 
818
 
 
819
        val->type = r->in.type;
 
820
        val->data = data_blob_talloc(p->mem_ctx, r->in.data, r->in.size);
 
821
 
 
822
        return reg_setvalue(key, r->in.name.name, val);
 
823
}
 
824
 
 
825
/*******************************************************************
 
826
 _winreg_DeleteKey
 
827
 ********************************************************************/
 
828
 
 
829
WERROR _winreg_DeleteKey(struct pipes_struct *p,
 
830
                         struct winreg_DeleteKey *r)
 
831
{
 
832
        struct registry_key *parent = find_regkey_by_hnd(p, r->in.handle);
 
833
 
 
834
        if ( !parent )
 
835
                return WERR_BADFID;
 
836
 
 
837
        return reg_deletekey(parent, r->in.key.name);
 
838
}
 
839
 
 
840
 
 
841
/*******************************************************************
 
842
 _winreg_DeleteValue
 
843
 ********************************************************************/
 
844
 
 
845
WERROR _winreg_DeleteValue(struct pipes_struct *p,
 
846
                           struct winreg_DeleteValue *r)
 
847
{
 
848
        struct registry_key *key = find_regkey_by_hnd(p, r->in.handle);
 
849
 
 
850
        if ( !key )
 
851
                return WERR_BADFID;
 
852
 
 
853
        return reg_deletevalue(key, r->in.value.name);
 
854
}
 
855
 
 
856
/*******************************************************************
 
857
 _winreg_GetKeySecurity
 
858
 ********************************************************************/
 
859
 
 
860
WERROR _winreg_GetKeySecurity(struct pipes_struct *p,
 
861
                              struct winreg_GetKeySecurity *r)
 
862
{
 
863
        struct registry_key *key = find_regkey_by_hnd(p, r->in.handle);
 
864
        WERROR err = WERR_OK;
 
865
        struct security_descriptor *secdesc = NULL;
 
866
        uint8 *data = NULL;
 
867
        size_t len = 0;
 
868
 
 
869
        if ( !key )
 
870
                return WERR_BADFID;
 
871
 
 
872
        /* access checks first */
 
873
 
 
874
        if ( !(key->key->access_granted & SEC_STD_READ_CONTROL) )
 
875
                return WERR_ACCESS_DENIED;
 
876
 
 
877
        err = reg_getkeysecurity(p->mem_ctx, key, &secdesc);
 
878
        if (!W_ERROR_IS_OK(err)) {
 
879
                return err;
 
880
        }
 
881
 
 
882
        err = ntstatus_to_werror(marshall_sec_desc(p->mem_ctx, secdesc,
 
883
                                                   &data, &len));
 
884
        if (!W_ERROR_IS_OK(err)) {
 
885
                return err;
 
886
        }
 
887
 
 
888
        if (len > r->out.sd->size) {
 
889
                r->out.sd->size = len;
 
890
                return WERR_INSUFFICIENT_BUFFER;
 
891
        }
 
892
 
 
893
        r->out.sd->size = len;
 
894
        r->out.sd->len = len;
 
895
        r->out.sd->data = data;
 
896
 
 
897
        return WERR_OK;
 
898
}
 
899
 
 
900
/*******************************************************************
 
901
 _winreg_SetKeySecurity
 
902
 ********************************************************************/
 
903
 
 
904
WERROR _winreg_SetKeySecurity(struct pipes_struct *p,
 
905
                              struct winreg_SetKeySecurity *r)
 
906
{
 
907
        struct registry_key *key = find_regkey_by_hnd(p, r->in.handle);
 
908
        struct security_descriptor *secdesc = NULL;
 
909
        WERROR err = WERR_OK;
 
910
 
 
911
        if ( !key )
 
912
                return WERR_BADFID;
 
913
 
 
914
        /* access checks first */
 
915
 
 
916
        if ( !(key->key->access_granted & SEC_STD_WRITE_DAC) )
 
917
                return WERR_ACCESS_DENIED;
 
918
 
 
919
        err = ntstatus_to_werror(unmarshall_sec_desc(p->mem_ctx, r->in.sd->data,
 
920
                                                     r->in.sd->len, &secdesc));
 
921
        if (!W_ERROR_IS_OK(err)) {
 
922
                return err;
 
923
        }
 
924
 
 
925
        return reg_setkeysecurity(key, secdesc);
 
926
}
 
927
 
 
928
/*******************************************************************
 
929
 _winreg_FlushKey
 
930
 ********************************************************************/
 
931
 
 
932
WERROR _winreg_FlushKey(struct pipes_struct *p,
 
933
                        struct winreg_FlushKey *r)
 
934
{
 
935
        /* I'm just replying OK because there's not a lot
 
936
           here I see to do i  --jerry */
 
937
 
 
938
        return WERR_OK;
 
939
}
 
940
 
 
941
/*******************************************************************
 
942
 _winreg_UnLoadKey
 
943
 ********************************************************************/
 
944
 
 
945
WERROR _winreg_UnLoadKey(struct pipes_struct *p,
 
946
                         struct winreg_UnLoadKey *r)
 
947
{
 
948
        /* fill in your code here if you think this call should
 
949
           do anything */
 
950
 
 
951
        p->rng_fault_state = True;
 
952
        return WERR_NOT_SUPPORTED;
 
953
}
 
954
 
 
955
/*******************************************************************
 
956
 _winreg_ReplaceKey
 
957
 ********************************************************************/
 
958
 
 
959
WERROR _winreg_ReplaceKey(struct pipes_struct *p,
 
960
                          struct winreg_ReplaceKey *r)
 
961
{
 
962
        /* fill in your code here if you think this call should
 
963
           do anything */
 
964
 
 
965
        p->rng_fault_state = True;
 
966
        return WERR_NOT_SUPPORTED;
 
967
}
 
968
 
 
969
/*******************************************************************
 
970
 _winreg_LoadKey
 
971
 ********************************************************************/
 
972
 
 
973
WERROR _winreg_LoadKey(struct pipes_struct *p,
 
974
                       struct winreg_LoadKey *r)
 
975
{
 
976
        /* fill in your code here if you think this call should
 
977
           do anything */
 
978
 
 
979
        p->rng_fault_state = True;
 
980
        return WERR_NOT_SUPPORTED;
 
981
}
 
982
 
 
983
/*******************************************************************
 
984
 _winreg_NotifyChangeKeyValue
 
985
 ********************************************************************/
 
986
 
 
987
WERROR _winreg_NotifyChangeKeyValue(struct pipes_struct *p,
 
988
                                    struct winreg_NotifyChangeKeyValue *r)
 
989
{
 
990
        return WERR_NOT_SUPPORTED;
 
991
}
 
992
 
 
993
/*******************************************************************
 
994
 _winreg_QueryMultipleValues
 
995
 ********************************************************************/
 
996
 
 
997
WERROR _winreg_QueryMultipleValues(struct pipes_struct *p,
 
998
                                   struct winreg_QueryMultipleValues *r)
 
999
{
 
1000
        struct winreg_QueryMultipleValues2 r2;
 
1001
        uint32_t needed = 0;
 
1002
 
 
1003
        r2.in.key_handle        = r->in.key_handle;
 
1004
        r2.in.values_in         = r->in.values_in;
 
1005
        r2.in.num_values        = r->in.num_values;
 
1006
        r2.in.offered           = r->in.buffer_size;
 
1007
        r2.in.buffer            = r->in.buffer;
 
1008
        r2.out.values_out       = r->out.values_out;
 
1009
        r2.out.needed           = &needed;
 
1010
        r2.out.buffer           = r->out.buffer;
 
1011
 
 
1012
        return _winreg_QueryMultipleValues2(p, &r2);
 
1013
}
 
1014
 
 
1015
/*******************************************************************
 
1016
 ********************************************************************/
 
1017
 
 
1018
static WERROR construct_multiple_entry(TALLOC_CTX *mem_ctx,
 
1019
                                       const char *valuename,
 
1020
                                       uint32_t value_length,
 
1021
                                       uint32_t offset,
 
1022
                                       enum winreg_Type type,
 
1023
                                       struct QueryMultipleValue *r)
 
1024
{
 
1025
        r->ve_valuename = talloc_zero(mem_ctx, struct winreg_ValNameBuf);
 
1026
        if (r->ve_valuename == NULL) {
 
1027
                return WERR_NOMEM;
 
1028
        }
 
1029
 
 
1030
        r->ve_valuename->name = talloc_strdup(r->ve_valuename, valuename ? valuename : "");
 
1031
        if (r->ve_valuename->name == NULL) {
 
1032
                return WERR_NOMEM;
 
1033
        }
 
1034
 
 
1035
        r->ve_valuename->size = strlen_m_term(r->ve_valuename->name)*2;
 
1036
        r->ve_valuelen = value_length;
 
1037
        r->ve_valueptr = offset;
 
1038
        r->ve_type = type;
 
1039
 
 
1040
        return WERR_OK;
 
1041
}
 
1042
 
 
1043
/*******************************************************************
 
1044
 _winreg_QueryMultipleValues2
 
1045
 ********************************************************************/
 
1046
 
 
1047
WERROR _winreg_QueryMultipleValues2(struct pipes_struct *p,
 
1048
                                    struct winreg_QueryMultipleValues2 *r)
 
1049
{
 
1050
        struct registry_key *regkey = find_regkey_by_hnd(p, r->in.key_handle);
 
1051
        struct registry_value *vals = NULL;
 
1052
        const char **names = NULL;
 
1053
        uint32_t offset = 0, num_vals = 0;
 
1054
        DATA_BLOB result = data_blob_null;
 
1055
        int i = 0;
 
1056
        WERROR err = WERR_OK;
 
1057
 
 
1058
        if (!regkey) {
 
1059
                return WERR_BADFID;
 
1060
        }
 
1061
 
 
1062
        names = talloc_zero_array(p->mem_ctx, const char *, r->in.num_values);
 
1063
        if (names == NULL) {
 
1064
                return WERR_NOMEM;
 
1065
        }
 
1066
 
 
1067
        for (i=0; i < r->in.num_values; i++) {
 
1068
                if (r->in.values_in[i].ve_valuename &&
 
1069
                    r->in.values_in[i].ve_valuename->name) {
 
1070
                        names[i] = talloc_strdup(names,
 
1071
                                r->in.values_in[i].ve_valuename->name);
 
1072
                        if (names[i] == NULL) {
 
1073
                                return WERR_NOMEM;
 
1074
                        }
 
1075
                }
 
1076
        }
 
1077
 
 
1078
        err = reg_querymultiplevalues(p->mem_ctx, regkey,
 
1079
                                      r->in.num_values, names,
 
1080
                                      &num_vals, &vals);
 
1081
        if (!W_ERROR_IS_OK(err)) {
 
1082
                return err;
 
1083
        }
 
1084
 
 
1085
        result = data_blob_talloc(p->mem_ctx, NULL, 0);
 
1086
 
 
1087
        for (i=0; i < r->in.num_values; i++) {
 
1088
                const char *valuename = NULL;
 
1089
 
 
1090
                if (vals[i].data.length > 0) {
 
1091
                        if (!data_blob_append(p->mem_ctx, &result,
 
1092
                                              vals[i].data.data,
 
1093
                                              vals[i].data.length)) {
 
1094
                                return WERR_NOMEM;
 
1095
                        }
 
1096
                }
 
1097
 
 
1098
                if (r->in.values_in[i].ve_valuename &&
 
1099
                    r->in.values_in[i].ve_valuename->name) {
 
1100
                        valuename = r->in.values_in[i].ve_valuename->name;
 
1101
                }
 
1102
 
 
1103
                err = construct_multiple_entry(r->out.values_out,
 
1104
                                               valuename,
 
1105
                                               vals[i].data.length,
 
1106
                                               offset,
 
1107
                                               vals[i].type,
 
1108
                                               &r->out.values_out[i]);
 
1109
                if (!W_ERROR_IS_OK(err)) {
 
1110
                        return err;
 
1111
                }
 
1112
 
 
1113
                offset += vals[i].data.length;
 
1114
        }
 
1115
 
 
1116
        *r->out.needed = result.length;
 
1117
 
 
1118
        if (r->in.num_values != num_vals) {
 
1119
                return WERR_BADFILE;
 
1120
        }
 
1121
 
 
1122
        if (*r->in.offered >= *r->out.needed) {
 
1123
                if (r->out.buffer) {
 
1124
                        memcpy(r->out.buffer, result.data, MIN(result.length, *r->in.offered));
 
1125
                }
 
1126
                return WERR_OK;
 
1127
        } else {
 
1128
                return WERR_MORE_DATA;
 
1129
        }
 
1130
}
 
1131
 
 
1132
/*******************************************************************
 
1133
 _winreg_DeleteKeyEx
 
1134
 ********************************************************************/
 
1135
 
 
1136
WERROR _winreg_DeleteKeyEx(struct pipes_struct *p,
 
1137
                           struct winreg_DeleteKeyEx *r)
 
1138
{
 
1139
        /* fill in your code here if you think this call should
 
1140
           do anything */
 
1141
 
 
1142
        p->rng_fault_state = True;
 
1143
        return WERR_NOT_SUPPORTED;
 
1144
}