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

« back to all changes in this revision

Viewing changes to source3/rpc_server/svcctl/srv_svcctl_reg.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
 *
 
4
 *  SVCCTL RPC server keys initialization
 
5
 *
 
6
 *  Copyright (c) 2005      Marcin Krzysztof Porwit
 
7
 *  Copyright (c) 2005      Gerald (Jerry) Carter
 
8
 *  Copyright (c) 2011      Andreas Schneider <asn@samba.org>
 
9
 *
 
10
 *  This program is free software; you can redistribute it and/or modify
 
11
 *  it under the terms of the GNU General Public License as published by
 
12
 *  the Free Software Foundation; either version 3 of the License, or
 
13
 *  (at your option) any later version.
 
14
 *
 
15
 *  This program is distributed in the hope that it will be useful,
 
16
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
17
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
18
 *  GNU General Public License for more details.
 
19
 *
 
20
 *  You should have received a copy of the GNU General Public License
 
21
 *  along with this program; if not, see <http://www.gnu.org/licenses/>.
 
22
 */
 
23
 
 
24
#include "includes.h"
 
25
#include "system/filesys.h"
 
26
#include "services/services.h"
 
27
#include "services/svc_winreg_glue.h"
 
28
#include "../librpc/gen_ndr/ndr_winreg_c.h"
 
29
#include "rpc_client/cli_winreg_int.h"
 
30
#include "rpc_client/cli_winreg.h"
 
31
#include "rpc_server/svcctl/srv_svcctl_reg.h"
 
32
#include "auth.h"
 
33
#include "registry/reg_backend_db.h"
 
34
 
 
35
#undef DBGC_CLASS
 
36
#define DBGC_CLASS DBGC_REGISTRY
 
37
 
 
38
#define TOP_LEVEL_SERVICES_KEY "SYSTEM\\CurrentControlSet\\Services"
 
39
 
 
40
struct rcinit_file_information {
 
41
        char *description;
 
42
};
 
43
 
 
44
struct service_display_info {
 
45
        const char *servicename;
 
46
        const char *daemon;
 
47
        const char *dispname;
 
48
        const char *description;
 
49
};
 
50
 
 
51
static struct service_display_info builtin_svcs[] = {
 
52
        {
 
53
                "Spooler",
 
54
                "smbd",
 
55
                "Print Spooler",
 
56
                "Internal service for spooling files to print devices"
 
57
        },
 
58
        {
 
59
                "NETLOGON",
 
60
                "smbd",
 
61
                "Net Logon",
 
62
                "File service providing access to policy and profile data (not"
 
63
                        "remotely manageable)"
 
64
        },
 
65
        {
 
66
                "RemoteRegistry",
 
67
                "smbd",
 
68
                "Remote Registry Service",
 
69
                "Internal service providing remote access to the Samba registry"
 
70
        },
 
71
        {
 
72
                "WINS",
 
73
                "nmbd",
 
74
                "Windows Internet Name Service (WINS)",
 
75
                "Internal service providing a NetBIOS point-to-point name server"
 
76
                        "(not remotely manageable)"
 
77
        },
 
78
        { NULL, NULL, NULL, NULL }
 
79
};
 
80
 
 
81
static struct service_display_info common_unix_svcs[] = {
 
82
  { "cups",          NULL, "Common Unix Printing System","Provides unified printing support for all operating systems" },
 
83
  { "postfix",       NULL, "Internet Mail Service",     "Provides support for sending and receiving electonic mail" },
 
84
  { "sendmail",      NULL, "Internet Mail Service",     "Provides support for sending and receiving electonic mail" },
 
85
  { "portmap",       NULL, "TCP Port to RPC PortMapper",NULL },
 
86
  { "xinetd",        NULL, "Internet Meta-Daemon",      NULL },
 
87
  { "inet",          NULL, "Internet Meta-Daemon",      NULL },
 
88
  { "xntpd",         NULL, "Network Time Service",      NULL },
 
89
  { "ntpd",          NULL, "Network Time Service",      NULL },
 
90
  { "lpd",           NULL, "BSD Print Spooler",         NULL },
 
91
  { "nfsserver",     NULL, "Network File Service",      NULL },
 
92
  { "cron",          NULL, "Scheduling Service",        NULL },
 
93
  { "at",            NULL, "Scheduling Service",        NULL },
 
94
  { "nscd",          NULL, "Name Service Cache Daemon", NULL },
 
95
  { "slapd",         NULL, "LDAP Directory Service",    NULL },
 
96
  { "ldap",          NULL, "LDAP DIrectory Service",    NULL },
 
97
  { "ypbind",        NULL, "NIS Directory Service",     NULL },
 
98
  { "courier-imap",  NULL, "IMAP4 Mail Service",        NULL },
 
99
  { "courier-pop3",  NULL, "POP3 Mail Service",         NULL },
 
100
  { "named",         NULL, "Domain Name Service",       NULL },
 
101
  { "bind",          NULL, "Domain Name Service",       NULL },
 
102
  { "httpd",         NULL, "HTTP Server",               NULL },
 
103
  { "apache",        NULL, "HTTP Server",               "Provides s highly scalable and flexible web server "
 
104
                                                        "capable of implementing various protocols incluing "
 
105
                                                        "but not limited to HTTP" },
 
106
  { "autofs",        NULL, "Automounter",               NULL },
 
107
  { "squid",         NULL, "Web Cache Proxy ",          NULL },
 
108
  { "perfcountd",    NULL, "Performance Monitoring Daemon", NULL },
 
109
  { "pgsql",         NULL, "PgSQL Database Server",     "Provides service for SQL database from Postgresql.org" },
 
110
  { "arpwatch",      NULL, "ARP Tables watcher",        "Provides service for monitoring ARP tables for changes" },
 
111
  { "dhcpd",         NULL, "DHCP Server",               "Provides service for dynamic host configuration and IP assignment" },
 
112
  { "nwserv",        NULL, "NetWare Server Emulator",   "Provides service for emulating Novell NetWare 3.12 server" },
 
113
  { "proftpd",       NULL, "Professional FTP Server",   "Provides high configurable service for FTP connection and "
 
114
                                                        "file transferring" },
 
115
  { "ssh2",          NULL, "SSH Secure Shell",          "Provides service for secure connection for remote administration" },
 
116
  { "sshd",          NULL, "SSH Secure Shell",          "Provides service for secure connection for remote administration" },
 
117
  { NULL, NULL, NULL, NULL }
 
118
};
 
119
 
 
120
/********************************************************************
 
121
 This is where we do the dirty work of filling in things like the
 
122
 Display name, Description, etc...
 
123
********************************************************************/
 
124
static char *svcctl_get_common_service_dispname(TALLOC_CTX *mem_ctx,
 
125
                                                const char *servicename)
 
126
{
 
127
        uint32_t i;
 
128
 
 
129
        for (i = 0; common_unix_svcs[i].servicename; i++) {
 
130
                if (strequal(servicename, common_unix_svcs[i].servicename)) {
 
131
                        char *dispname;
 
132
                        dispname = talloc_asprintf(mem_ctx, "%s (%s)",
 
133
                                        common_unix_svcs[i].dispname,
 
134
                                        common_unix_svcs[i].servicename);
 
135
                        if (dispname == NULL) {
 
136
                                return NULL;
 
137
                        }
 
138
                        return dispname;
 
139
                }
 
140
        }
 
141
 
 
142
        return talloc_strdup(mem_ctx, servicename);
 
143
}
 
144
 
 
145
/********************************************************************
 
146
********************************************************************/
 
147
static char *svcctl_cleanup_string(TALLOC_CTX *mem_ctx,
 
148
                                   const char *string)
 
149
{
 
150
        char *clean = NULL;
 
151
        char *begin, *end;
 
152
 
 
153
        clean = talloc_strdup(mem_ctx, string);
 
154
        if (clean == NULL) {
 
155
                return NULL;
 
156
        }
 
157
        begin = clean;
 
158
 
 
159
        /* trim any beginning whilespace */
 
160
        while (isspace(*begin)) {
 
161
                begin++;
 
162
        }
 
163
 
 
164
        if (*begin == '\0') {
 
165
                return NULL;
 
166
        }
 
167
 
 
168
        /* trim any trailing whitespace or carriage returns.
 
169
           Start at the end and move backwards */
 
170
 
 
171
        end = begin + strlen(begin) - 1;
 
172
 
 
173
        while (isspace(*end) || *end=='\n' || *end=='\r') {
 
174
                *end = '\0';
 
175
                end--;
 
176
        }
 
177
 
 
178
        return begin;
 
179
}
 
180
 
 
181
/********************************************************************
 
182
********************************************************************/
 
183
static bool read_init_file(TALLOC_CTX *mem_ctx,
 
184
                           const char *servicename,
 
185
                           struct rcinit_file_information **service_info)
 
186
{
 
187
        struct rcinit_file_information *info = NULL;
 
188
        char *filepath = NULL;
 
189
        char str[1024];
 
190
        XFILE *f = NULL;
 
191
        char *p = NULL;
 
192
 
 
193
        info = talloc_zero(mem_ctx, struct rcinit_file_information);
 
194
        if (info == NULL) {
 
195
                return false;
 
196
        }
 
197
 
 
198
        /* attempt the file open */
 
199
 
 
200
        filepath = talloc_asprintf(mem_ctx,
 
201
                                   "%s/%s/%s",
 
202
                                   get_dyn_MODULESDIR(),
 
203
                                   SVCCTL_SCRIPT_DIR,
 
204
                                   servicename);
 
205
        if (filepath == NULL) {
 
206
                return false;
 
207
        }
 
208
        f = x_fopen( filepath, O_RDONLY, 0 );
 
209
        if (f == NULL) {
 
210
                DEBUG(0,("read_init_file: failed to open [%s]\n", filepath));
 
211
                return false;
 
212
        }
 
213
 
 
214
        while ((x_fgets(str, sizeof(str) - 1, f)) != NULL) {
 
215
                /* ignore everything that is not a full line
 
216
                   comment starting with a '#' */
 
217
 
 
218
                if (str[0] != '#') {
 
219
                        continue;
 
220
                }
 
221
 
 
222
                /* Look for a line like '^#.*Description:' */
 
223
 
 
224
                p = strstr(str, "Description:");
 
225
                if (p != NULL) {
 
226
                        char *desc;
 
227
 
 
228
                        p += strlen( "Description:" ) + 1;
 
229
                        if (p == NULL) {
 
230
                                break;
 
231
                        }
 
232
 
 
233
                        desc = svcctl_cleanup_string(mem_ctx, p);
 
234
                        if (desc != NULL) {
 
235
                                info->description = talloc_strdup(info, desc);
 
236
                        }
 
237
                }
 
238
        }
 
239
 
 
240
        x_fclose(f);
 
241
 
 
242
        if (info->description == NULL) {
 
243
                info->description = talloc_strdup(info,
 
244
                                                  "External Unix Service");
 
245
                if (info->description == NULL) {
 
246
                        return false;
 
247
                }
 
248
        }
 
249
 
 
250
        *service_info = info;
 
251
 
 
252
        return true;
 
253
}
 
254
 
 
255
static bool svcctl_add_service(TALLOC_CTX *mem_ctx,
 
256
                               struct dcerpc_binding_handle *h,
 
257
                               struct policy_handle *hive_hnd,
 
258
                               const char *key,
 
259
                               uint32_t access_mask,
 
260
                               const char *name)
 
261
{
 
262
        enum winreg_CreateAction action = REG_ACTION_NONE;
 
263
        struct security_descriptor *sd = NULL;
 
264
        struct policy_handle key_hnd;
 
265
        struct winreg_String wkey;
 
266
        struct winreg_String wkeyclass;
 
267
        char *description = NULL;
 
268
        char *dname = NULL;
 
269
        char *ipath = NULL;
 
270
        bool ok = false;
 
271
        uint32_t i;
 
272
        NTSTATUS status;
 
273
        WERROR result = WERR_OK;
 
274
 
 
275
        ZERO_STRUCT(key_hnd);
 
276
 
 
277
        ZERO_STRUCT(wkey);
 
278
        wkey.name = talloc_asprintf(mem_ctx, "%s\\%s", key, name);
 
279
        if (wkey.name == NULL) {
 
280
                goto done;
 
281
        }
 
282
 
 
283
        ZERO_STRUCT(wkeyclass);
 
284
        wkeyclass.name = "";
 
285
 
 
286
        status = dcerpc_winreg_CreateKey(h,
 
287
                                         mem_ctx,
 
288
                                         hive_hnd,
 
289
                                         wkey,
 
290
                                         wkeyclass,
 
291
                                         0,
 
292
                                         access_mask,
 
293
                                         NULL,
 
294
                                         &key_hnd,
 
295
                                         &action,
 
296
                                         &result);
 
297
        if (!NT_STATUS_IS_OK(status)) {
 
298
                DEBUG(0, ("svcctl_init_winreg_keys: Could not create key %s: %s\n",
 
299
                        wkey.name, nt_errstr(status)));
 
300
                goto done;
 
301
        }
 
302
        if (!W_ERROR_IS_OK(result)) {
 
303
                DEBUG(0, ("svcctl_init_winreg_keys: Could not create key %s: %s\n",
 
304
                        wkey.name, win_errstr(result)));
 
305
                goto done;
 
306
        }
 
307
 
 
308
        /* These values are hardcoded in all QueryServiceConfig() replies.
 
309
           I'm just storing them here for cosmetic purposes */
 
310
        status = dcerpc_winreg_set_dword(mem_ctx,
 
311
                                         h,
 
312
                                         &key_hnd,
 
313
                                         "Start",
 
314
                                         SVCCTL_AUTO_START,
 
315
                                         &result);
 
316
        if (!NT_STATUS_IS_OK(status)) {
 
317
                DEBUG(0, ("svcctl_init_winreg_keys: Could not create value: %s\n",
 
318
                          nt_errstr(status)));
 
319
                goto done;
 
320
        }
 
321
        if (!W_ERROR_IS_OK(result)) {
 
322
                DEBUG(0, ("svcctl_init_winreg_keys: Could not create value: %s\n",
 
323
                          win_errstr(result)));
 
324
                goto done;
 
325
        }
 
326
 
 
327
        status = dcerpc_winreg_set_dword(mem_ctx,
 
328
                                         h,
 
329
                                         &key_hnd,
 
330
                                         "Type",
 
331
                                         SERVICE_TYPE_WIN32_OWN_PROCESS,
 
332
                                         &result);
 
333
        if (!NT_STATUS_IS_OK(status)) {
 
334
                DEBUG(0, ("svcctl_init_winreg_keys: Could not create value: %s\n",
 
335
                          nt_errstr(status)));
 
336
                goto done;
 
337
        }
 
338
        if (!W_ERROR_IS_OK(result)) {
 
339
                DEBUG(0, ("svcctl_init_winreg_keys: Could not create value: %s\n",
 
340
                          win_errstr(result)));
 
341
                goto done;
 
342
        }
 
343
 
 
344
        status = dcerpc_winreg_set_dword(mem_ctx,
 
345
                                         h,
 
346
                                         &key_hnd,
 
347
                                         "ErrorControl",
 
348
                                         SVCCTL_SVC_ERROR_NORMAL,
 
349
                                         &result);
 
350
        if (!NT_STATUS_IS_OK(status)) {
 
351
                DEBUG(0, ("svcctl_init_winreg_keys: Could not create value: %s\n",
 
352
                          nt_errstr(status)));
 
353
                goto done;
 
354
        }
 
355
        if (!W_ERROR_IS_OK(result)) {
 
356
                DEBUG(0, ("svcctl_init_winreg_keys: Could not create value: %s\n",
 
357
                          win_errstr(result)));
 
358
                goto done;
 
359
        }
 
360
 
 
361
        status = dcerpc_winreg_set_sz(mem_ctx,
 
362
                                      h,
 
363
                                      &key_hnd,
 
364
                                      "ObjectName",
 
365
                                      "LocalSystem",
 
366
                                      &result);
 
367
        if (!NT_STATUS_IS_OK(status)) {
 
368
                DEBUG(0, ("svcctl_init_winreg_keys: Could not create value: %s\n",
 
369
                          nt_errstr(status)));
 
370
                goto done;
 
371
        }
 
372
        if (!W_ERROR_IS_OK(result)) {
 
373
                DEBUG(0, ("svcctl_init_winreg_keys: Could not create value: %s\n",
 
374
                          win_errstr(result)));
 
375
                goto done;
 
376
        }
 
377
 
 
378
        /*
 
379
         * Special considerations for internal services and the DisplayName
 
380
         * value.
 
381
         */
 
382
        for (i = 0; builtin_svcs[i].servicename; i++) {
 
383
                if (strequal(name, builtin_svcs[i].servicename)) {
 
384
                        ipath = talloc_asprintf(mem_ctx,
 
385
                                                "%s/%s/%s",
 
386
                                                get_dyn_MODULESDIR(),
 
387
                                                SVCCTL_SCRIPT_DIR,
 
388
                                                builtin_svcs[i].daemon);
 
389
                        description = talloc_strdup(mem_ctx, builtin_svcs[i].description);
 
390
                        dname = talloc_strdup(mem_ctx, builtin_svcs[i].dispname);
 
391
                        break;
 
392
                }
 
393
        }
 
394
 
 
395
        if (ipath == NULL || dname == NULL || description == NULL) {
 
396
                goto done;
 
397
        }
 
398
 
 
399
        /* Default to an external service if we haven't found a match */
 
400
        if (builtin_svcs[i].servicename == NULL) {
 
401
                struct rcinit_file_information *init_info = NULL;
 
402
                char *dispname = NULL;
 
403
 
 
404
                ipath = talloc_asprintf(mem_ctx,
 
405
                                        "%s/%s/%s",
 
406
                                        get_dyn_MODULESDIR(),
 
407
                                        SVCCTL_SCRIPT_DIR,
 
408
                                        name);
 
409
 
 
410
                /* lookup common unix display names */
 
411
                dispname = svcctl_get_common_service_dispname(mem_ctx, name);
 
412
                dname = talloc_strdup(mem_ctx, dispname ? dispname : "");
 
413
 
 
414
                /* get info from init file itself */
 
415
                if (read_init_file(mem_ctx, name, &init_info)) {
 
416
                        description = talloc_strdup(mem_ctx,
 
417
                                                    init_info->description);
 
418
                } else {
 
419
                        description = talloc_strdup(mem_ctx,
 
420
                                                    "External Unix Service");
 
421
                }
 
422
        }
 
423
 
 
424
        if (ipath == NULL || dname == NULL || description == NULL) {
 
425
                goto done;
 
426
        }
 
427
 
 
428
        status = dcerpc_winreg_set_sz(mem_ctx,
 
429
                                      h,
 
430
                                      &key_hnd,
 
431
                                      "DisplayName",
 
432
                                      dname,
 
433
                                      &result);
 
434
        if (!NT_STATUS_IS_OK(status)) {
 
435
                DEBUG(0, ("svcctl_init_winreg_keys: Could not create value: %s\n",
 
436
                          nt_errstr(status)));
 
437
                goto done;
 
438
        }
 
439
        if (!W_ERROR_IS_OK(result)) {
 
440
                DEBUG(0, ("svcctl_init_winreg_keys: Could not create value: %s\n",
 
441
                          win_errstr(result)));
 
442
                goto done;
 
443
        }
 
444
 
 
445
        status = dcerpc_winreg_set_sz(mem_ctx,
 
446
                                      h,
 
447
                                      &key_hnd,
 
448
                                      "ImagePath",
 
449
                                      ipath,
 
450
                                      &result);
 
451
        if (!NT_STATUS_IS_OK(status)) {
 
452
                DEBUG(0, ("svcctl_init_winreg_keys: Could not create value: %s\n",
 
453
                          nt_errstr(status)));
 
454
                goto done;
 
455
        }
 
456
        if (!W_ERROR_IS_OK(result)) {
 
457
                DEBUG(0, ("svcctl_init_winreg_keys: Could not create value: %s\n",
 
458
                          win_errstr(result)));
 
459
                goto done;
 
460
        }
 
461
 
 
462
        status = dcerpc_winreg_set_sz(mem_ctx,
 
463
                                      h,
 
464
                                      &key_hnd,
 
465
                                      "Description",
 
466
                                      description,
 
467
                                      &result);
 
468
        if (!NT_STATUS_IS_OK(status)) {
 
469
                DEBUG(0, ("svcctl_init_winreg_keys: Could not create value: %s\n",
 
470
                          nt_errstr(status)));
 
471
                goto done;
 
472
        }
 
473
        if (!W_ERROR_IS_OK(result)) {
 
474
                DEBUG(0, ("svcctl_init_winreg_keys: Could not create value: %s\n",
 
475
                          win_errstr(result)));
 
476
                goto done;
 
477
        }
 
478
 
 
479
        sd = svcctl_gen_service_sd(mem_ctx);
 
480
        if (sd == NULL) {
 
481
                DEBUG(0, ("add_new_svc_name: Failed to create default "
 
482
                          "sec_desc!\n"));
 
483
                goto done;
 
484
        }
 
485
 
 
486
        if (is_valid_policy_hnd(&key_hnd)) {
 
487
                dcerpc_winreg_CloseKey(h, mem_ctx, &key_hnd, &result);
 
488
        }
 
489
        ZERO_STRUCT(key_hnd);
 
490
 
 
491
        ZERO_STRUCT(wkey);
 
492
        wkey.name = talloc_asprintf(mem_ctx, "%s\\%s\\Security", key, name);
 
493
        if (wkey.name == NULL) {
 
494
                result = WERR_NOMEM;
 
495
                goto done;
 
496
        }
 
497
 
 
498
        ZERO_STRUCT(wkeyclass);
 
499
        wkeyclass.name = "";
 
500
 
 
501
        status = dcerpc_winreg_CreateKey(h,
 
502
                                         mem_ctx,
 
503
                                         hive_hnd,
 
504
                                         wkey,
 
505
                                         wkeyclass,
 
506
                                         0,
 
507
                                         access_mask,
 
508
                                         NULL,
 
509
                                         &key_hnd,
 
510
                                         &action,
 
511
                                         &result);
 
512
        if (!NT_STATUS_IS_OK(status)) {
 
513
                DEBUG(0, ("eventlog_init_winreg_keys: Could not create key %s: %s\n",
 
514
                        wkey.name, nt_errstr(status)));
 
515
                goto done;
 
516
        }
 
517
        if (!W_ERROR_IS_OK(result)) {
 
518
                DEBUG(0, ("eventlog_init_winreg_keys: Could not create key %s: %s\n",
 
519
                        wkey.name, win_errstr(result)));
 
520
                goto done;
 
521
        }
 
522
 
 
523
        status = dcerpc_winreg_set_sd(mem_ctx,
 
524
                                      h,
 
525
                                      &key_hnd,
 
526
                                      "Security",
 
527
                                      sd,
 
528
                                      &result);
 
529
        if (!NT_STATUS_IS_OK(status)) {
 
530
                DEBUG(0, ("svcctl_init_winreg_keys: Could not create value: %s\n",
 
531
                          nt_errstr(status)));
 
532
                goto done;
 
533
        }
 
534
        if (!W_ERROR_IS_OK(result)) {
 
535
                DEBUG(0, ("svcctl_init_winreg_keys: Could not create value: %s\n",
 
536
                          win_errstr(result)));
 
537
                goto done;
 
538
        }
 
539
 
 
540
        ok = true;
 
541
done:
 
542
        if (is_valid_policy_hnd(&key_hnd)) {
 
543
                dcerpc_winreg_CloseKey(h, mem_ctx, &key_hnd, &result);
 
544
        }
 
545
 
 
546
        return ok;
 
547
}
 
548
 
 
549
bool svcctl_init_winreg(struct messaging_context *msg_ctx)
 
550
{
 
551
        struct dcerpc_binding_handle *h = NULL;
 
552
        uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
 
553
        struct policy_handle hive_hnd, key_hnd;
 
554
        const char **service_list = lp_svcctl_list();
 
555
        const char **subkeys = NULL;
 
556
        uint32_t num_subkeys = 0;
 
557
        char *key = NULL;
 
558
        uint32_t i;
 
559
        NTSTATUS status;
 
560
        WERROR result = WERR_OK;
 
561
        bool ok = false;
 
562
        TALLOC_CTX *tmp_ctx;
 
563
 
 
564
        tmp_ctx = talloc_stackframe();
 
565
        if (tmp_ctx == NULL) {
 
566
                return false;
 
567
        }
 
568
 
 
569
        DEBUG(3, ("Initialise the svcctl registry keys if needed.\n"));
 
570
 
 
571
        ZERO_STRUCT(hive_hnd);
 
572
        ZERO_STRUCT(key_hnd);
 
573
 
 
574
        key = talloc_strdup(tmp_ctx, TOP_LEVEL_SERVICES_KEY);
 
575
        if (key == NULL) {
 
576
                goto done;
 
577
        }
 
578
 
 
579
        result = regdb_open();
 
580
        if (!W_ERROR_IS_OK(result)) {
 
581
                DEBUG(10, ("regdb_open failed: %s\n",
 
582
                           win_errstr(result)));
 
583
                goto done;
 
584
        }
 
585
        result = regdb_transaction_start();
 
586
        if (!W_ERROR_IS_OK(result)) {
 
587
                DEBUG(10, ("regdb_transaction_start failed: %s\n",
 
588
                           win_errstr(result)));
 
589
                goto done;
 
590
        }
 
591
 
 
592
        status = dcerpc_winreg_int_hklm_openkey(tmp_ctx,
 
593
                                                get_session_info_system(),
 
594
                                                msg_ctx,
 
595
                                                &h,
 
596
                                                key,
 
597
                                                false,
 
598
                                                access_mask,
 
599
                                                &hive_hnd,
 
600
                                                &key_hnd,
 
601
                                                &result);
 
602
        if (!NT_STATUS_IS_OK(status)) {
 
603
                DEBUG(0, ("svcctl_init_winreg: Could not open %s - %s\n",
 
604
                          key, nt_errstr(status)));
 
605
                goto done;
 
606
        }
 
607
        if (!W_ERROR_IS_OK(result)) {
 
608
                DEBUG(0, ("svcctl_init_winreg: Could not open %s - %s\n",
 
609
                          key, win_errstr(result)));
 
610
                goto done;
 
611
        }
 
612
 
 
613
        /* get all subkeys */
 
614
        status = dcerpc_winreg_enum_keys(tmp_ctx,
 
615
                                         h,
 
616
                                         &key_hnd,
 
617
                                         &num_subkeys,
 
618
                                         &subkeys,
 
619
                                         &result);
 
620
        if (!NT_STATUS_IS_OK(status)) {
 
621
                DEBUG(0, ("svcctl_init_winreg: Could enum keys at %s - %s\n",
 
622
                          key, nt_errstr(status)));
 
623
                goto done;
 
624
        }
 
625
        if (!W_ERROR_IS_OK(result)) {
 
626
                DEBUG(0, ("svcctl_init_winreg: Could enum keys at %s - %s\n",
 
627
                          key, win_errstr(result)));
 
628
                goto done;
 
629
        }
 
630
 
 
631
        for (i = 0; builtin_svcs[i].servicename != NULL; i++) {
 
632
                uint32_t j;
 
633
                bool skip = false;
 
634
 
 
635
                for (j = 0; j < num_subkeys; j++) {
 
636
                        if (strequal(subkeys[i], builtin_svcs[i].servicename)) {
 
637
                                skip = true;
 
638
                        }
 
639
                }
 
640
 
 
641
                if (skip) {
 
642
                        continue;
 
643
                }
 
644
 
 
645
                ok = svcctl_add_service(tmp_ctx,
 
646
                                        h,
 
647
                                        &hive_hnd,
 
648
                                        key,
 
649
                                        access_mask,
 
650
                                        builtin_svcs[i].servicename);
 
651
                if (!ok) {
 
652
                        goto done;
 
653
                }
 
654
        }
 
655
 
 
656
        for (i = 0; service_list && service_list[i]; i++) {
 
657
                uint32_t j;
 
658
                bool skip = false;
 
659
 
 
660
                for (j = 0; j < num_subkeys; j++) {
 
661
                        if (strequal(subkeys[i], service_list[i])) {
 
662
                                skip = true;
 
663
                        }
 
664
                }
 
665
 
 
666
                if (skip) {
 
667
                        continue;
 
668
                }
 
669
 
 
670
                ok = svcctl_add_service(tmp_ctx,
 
671
                                        h,
 
672
                                        &hive_hnd,
 
673
                                        key,
 
674
                                        access_mask,
 
675
                                        service_list[i]);
 
676
                if (is_valid_policy_hnd(&key_hnd)) {
 
677
                        dcerpc_winreg_CloseKey(h, tmp_ctx, &key_hnd, &result);
 
678
                }
 
679
                ZERO_STRUCT(key_hnd);
 
680
 
 
681
                if (!ok) {
 
682
                        goto done;
 
683
                }
 
684
        }
 
685
 
 
686
done:
 
687
        if (is_valid_policy_hnd(&key_hnd)) {
 
688
                dcerpc_winreg_CloseKey(h, tmp_ctx, &key_hnd, &result);
 
689
        }
 
690
 
 
691
        if (ok) {
 
692
                result = regdb_transaction_commit();
 
693
                if (!W_ERROR_IS_OK(result)) {
 
694
                        DEBUG(10, ("regdb_transaction_commit failed: %s\n",
 
695
                                   win_errstr(result)));
 
696
                }
 
697
        } else {
 
698
                result = regdb_transaction_cancel();
 
699
                if (!W_ERROR_IS_OK(result)) {
 
700
                        DEBUG(10, ("regdb_transaction_cancel failed: %s\n",
 
701
                                   win_errstr(result)));
 
702
                }
 
703
        }
 
704
        regdb_close();
 
705
        return ok;
 
706
}
 
707
 
 
708
/* vim: set ts=8 sw=8 noet cindent syntax=c.doxygen: */