~ubuntu-branches/ubuntu/vivid/samba/vivid

« back to all changes in this revision

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