LCOV - code coverage report
Current view: top level - source3/rpc_server/svcctl - srv_svcctl_reg.c (source / functions) Hit Total Coverage
Test: coverage report for master 6248eab5 Lines: 110 254 43.3 %
Date: 2021-08-25 13:27:56 Functions: 2 5 40.0 %

          Line data    Source code
       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 including "
     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           0 : static char *svcctl_get_common_service_dispname(TALLOC_CTX *mem_ctx,
     125             :                                                 const char *servicename)
     126             : {
     127             :         uint32_t i;
     128             : 
     129           0 :         for (i = 0; common_unix_svcs[i].servicename; i++) {
     130           0 :                 if (strequal(servicename, common_unix_svcs[i].servicename)) {
     131             :                         char *dispname;
     132           0 :                         dispname = talloc_asprintf(mem_ctx, "%s (%s)",
     133             :                                         common_unix_svcs[i].dispname,
     134             :                                         common_unix_svcs[i].servicename);
     135           0 :                         if (dispname == NULL) {
     136           0 :                                 return NULL;
     137             :                         }
     138           0 :                         return dispname;
     139             :                 }
     140             :         }
     141             : 
     142           0 :         return talloc_strdup(mem_ctx, servicename);
     143             : }
     144             : 
     145             : /********************************************************************
     146             : ********************************************************************/
     147           0 : static char *svcctl_cleanup_string(TALLOC_CTX *mem_ctx,
     148             :                                    const char *string)
     149             : {
     150           0 :         char *clean = NULL;
     151             :         char *begin, *end;
     152             : 
     153           0 :         clean = talloc_strdup(mem_ctx, string);
     154           0 :         if (clean == NULL) {
     155           0 :                 return NULL;
     156             :         }
     157           0 :         begin = clean;
     158             : 
     159             :         /* trim any beginning whilespace */
     160           0 :         while (isspace(*begin)) {
     161           0 :                 begin++;
     162             :         }
     163             : 
     164           0 :         if (*begin == '\0') {
     165           0 :                 return NULL;
     166             :         }
     167             : 
     168             :         /* trim any trailing whitespace or carriage returns.
     169             :            Start at the end and move backwards */
     170             : 
     171           0 :         end = begin + strlen(begin) - 1;
     172             : 
     173           0 :         while (isspace(*end) || *end=='\n' || *end=='\r') {
     174           0 :                 *end = '\0';
     175           0 :                 end--;
     176             :         }
     177             : 
     178           0 :         return begin;
     179             : }
     180             : 
     181             : /********************************************************************
     182             : ********************************************************************/
     183           0 : static bool read_init_file(TALLOC_CTX *mem_ctx,
     184             :                            const char *servicename,
     185             :                            struct rcinit_file_information **service_info)
     186             : {
     187           0 :         struct rcinit_file_information *info = NULL;
     188           0 :         char *filepath = NULL;
     189             :         char str[1024];
     190           0 :         FILE *f = NULL;
     191           0 :         char *p = NULL;
     192             : 
     193           0 :         info = talloc_zero(mem_ctx, struct rcinit_file_information);
     194           0 :         if (info == NULL) {
     195           0 :                 return false;
     196             :         }
     197             : 
     198             :         /* attempt the file open */
     199             : 
     200           0 :         filepath = talloc_asprintf(mem_ctx,
     201             :                                    "%s/%s/%s",
     202             :                                    get_dyn_MODULESDIR(),
     203             :                                    SVCCTL_SCRIPT_DIR,
     204             :                                    servicename);
     205           0 :         if (filepath == NULL) {
     206           0 :                 return false;
     207             :         }
     208           0 :         f = fopen( filepath, "r" );
     209           0 :         if (f == NULL) {
     210           0 :                 DEBUG(0,("read_init_file: failed to open [%s]\n", filepath));
     211           0 :                 return false;
     212             :         }
     213             : 
     214           0 :         while ((fgets(str, sizeof(str) - 1, f)) != NULL) {
     215             :                 /* ignore everything that is not a full line
     216             :                    comment starting with a '#' */
     217             : 
     218           0 :                 if (str[0] != '#') {
     219           0 :                         continue;
     220             :                 }
     221             : 
     222             :                 /* Look for a line like '^#.*Description:' */
     223             : 
     224           0 :                 p = strstr(str, "Description:");
     225           0 :                 if (p != NULL) {
     226             :                         char *desc;
     227           0 :                         size_t len = strlen(p);
     228             : 
     229           0 :                         if (len <= 12) {
     230           0 :                                 break;
     231             :                         }
     232             : 
     233           0 :                         desc = svcctl_cleanup_string(mem_ctx, p + 12);
     234           0 :                         if (desc != NULL) {
     235           0 :                                 info->description = talloc_strdup(info, desc);
     236             :                         }
     237             :                 }
     238             :         }
     239             : 
     240           0 :         fclose(f);
     241             : 
     242           0 :         if (info->description == NULL) {
     243           0 :                 info->description = talloc_strdup(info,
     244             :                                                   "External Unix Service");
     245           0 :                 if (info->description == NULL) {
     246           0 :                         return false;
     247             :                 }
     248             :         }
     249             : 
     250           0 :         *service_info = info;
     251             : 
     252           0 :         return true;
     253             : }
     254             : 
     255         300 : 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         300 :         enum winreg_CreateAction action = REG_ACTION_NONE;
     263         300 :         struct security_descriptor *sd = NULL;
     264             :         struct policy_handle key_hnd;
     265             :         struct winreg_String wkey;
     266             :         struct winreg_String wkeyclass;
     267         300 :         char *description = NULL;
     268         300 :         char *dname = NULL;
     269         300 :         char *ipath = NULL;
     270         300 :         bool ok = false;
     271             :         uint32_t i;
     272             :         NTSTATUS status;
     273         300 :         WERROR result = WERR_OK;
     274             : 
     275         300 :         ZERO_STRUCT(key_hnd);
     276             : 
     277         300 :         ZERO_STRUCT(wkey);
     278         300 :         wkey.name = talloc_asprintf(mem_ctx, "%s\\%s", key, name);
     279         300 :         if (wkey.name == NULL) {
     280           0 :                 goto done;
     281             :         }
     282             : 
     283         300 :         ZERO_STRUCT(wkeyclass);
     284         300 :         wkeyclass.name = "";
     285             : 
     286         300 :         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         300 :         if (!NT_STATUS_IS_OK(status)) {
     298           0 :                 DEBUG(0, ("svcctl_init_winreg_keys: Could not create key %s: %s\n",
     299             :                         wkey.name, nt_errstr(status)));
     300           0 :                 goto done;
     301             :         }
     302         300 :         if (!W_ERROR_IS_OK(result)) {
     303           0 :                 DEBUG(0, ("svcctl_init_winreg_keys: Could not create key %s: %s\n",
     304             :                         wkey.name, win_errstr(result)));
     305           0 :                 goto done;
     306             :         }
     307             : 
     308             :         /* These values are hardcoded in all QueryServiceConfig() replies.
     309             :            I'm just storing them here for cosmetic purposes */
     310         300 :         status = dcerpc_winreg_set_dword(mem_ctx,
     311             :                                          h,
     312             :                                          &key_hnd,
     313             :                                          "Start",
     314             :                                          SVCCTL_AUTO_START,
     315             :                                          &result);
     316         300 :         if (!NT_STATUS_IS_OK(status)) {
     317           0 :                 DEBUG(0, ("svcctl_init_winreg_keys: Could not create value: %s\n",
     318             :                           nt_errstr(status)));
     319           0 :                 goto done;
     320             :         }
     321         300 :         if (!W_ERROR_IS_OK(result)) {
     322           0 :                 DEBUG(0, ("svcctl_init_winreg_keys: Could not create value: %s\n",
     323             :                           win_errstr(result)));
     324           0 :                 goto done;
     325             :         }
     326             : 
     327         300 :         status = dcerpc_winreg_set_dword(mem_ctx,
     328             :                                          h,
     329             :                                          &key_hnd,
     330             :                                          "Type",
     331             :                                          SERVICE_TYPE_WIN32_OWN_PROCESS,
     332             :                                          &result);
     333         300 :         if (!NT_STATUS_IS_OK(status)) {
     334           0 :                 DEBUG(0, ("svcctl_init_winreg_keys: Could not create value: %s\n",
     335             :                           nt_errstr(status)));
     336           0 :                 goto done;
     337             :         }
     338         300 :         if (!W_ERROR_IS_OK(result)) {
     339           0 :                 DEBUG(0, ("svcctl_init_winreg_keys: Could not create value: %s\n",
     340             :                           win_errstr(result)));
     341           0 :                 goto done;
     342             :         }
     343             : 
     344         300 :         status = dcerpc_winreg_set_dword(mem_ctx,
     345             :                                          h,
     346             :                                          &key_hnd,
     347             :                                          "ErrorControl",
     348             :                                          SVCCTL_SVC_ERROR_NORMAL,
     349             :                                          &result);
     350         300 :         if (!NT_STATUS_IS_OK(status)) {
     351           0 :                 DEBUG(0, ("svcctl_init_winreg_keys: Could not create value: %s\n",
     352             :                           nt_errstr(status)));
     353           0 :                 goto done;
     354             :         }
     355         300 :         if (!W_ERROR_IS_OK(result)) {
     356           0 :                 DEBUG(0, ("svcctl_init_winreg_keys: Could not create value: %s\n",
     357             :                           win_errstr(result)));
     358           0 :                 goto done;
     359             :         }
     360             : 
     361         300 :         status = dcerpc_winreg_set_sz(mem_ctx,
     362             :                                       h,
     363             :                                       &key_hnd,
     364             :                                       "ObjectName",
     365             :                                       "LocalSystem",
     366             :                                       &result);
     367         300 :         if (!NT_STATUS_IS_OK(status)) {
     368           0 :                 DEBUG(0, ("svcctl_init_winreg_keys: Could not create value: %s\n",
     369             :                           nt_errstr(status)));
     370           0 :                 goto done;
     371             :         }
     372         300 :         if (!W_ERROR_IS_OK(result)) {
     373           0 :                 DEBUG(0, ("svcctl_init_winreg_keys: Could not create value: %s\n",
     374             :                           win_errstr(result)));
     375           0 :                 goto done;
     376             :         }
     377             : 
     378             :         /*
     379             :          * Special considerations for internal services and the DisplayName
     380             :          * value.
     381             :          */
     382         742 :         for (i = 0; builtin_svcs[i].servicename; i++) {
     383         750 :                 if (strequal(name, builtin_svcs[i].servicename)) {
     384         300 :                         ipath = talloc_asprintf(mem_ctx,
     385             :                                                 "%s/%s/%s",
     386             :                                                 get_dyn_MODULESDIR(),
     387             :                                                 SVCCTL_SCRIPT_DIR,
     388             :                                                 builtin_svcs[i].daemon);
     389         300 :                         description = talloc_strdup(mem_ctx, builtin_svcs[i].description);
     390         300 :                         dname = talloc_strdup(mem_ctx, builtin_svcs[i].dispname);
     391         300 :                         break;
     392             :                 }
     393             :         }
     394             : 
     395             :         /* Default to an external service if we haven't found a match */
     396         300 :         if (builtin_svcs[i].servicename == NULL) {
     397           0 :                 struct rcinit_file_information *init_info = NULL;
     398           0 :                 char *dispname = NULL;
     399             : 
     400           0 :                 ipath = talloc_asprintf(mem_ctx,
     401             :                                         "%s/%s/%s",
     402             :                                         get_dyn_MODULESDIR(),
     403             :                                         SVCCTL_SCRIPT_DIR,
     404             :                                         name);
     405             : 
     406             :                 /* lookup common unix display names */
     407           0 :                 dispname = svcctl_get_common_service_dispname(mem_ctx, name);
     408           0 :                 dname = talloc_strdup(mem_ctx, dispname ? dispname : "");
     409             : 
     410             :                 /* get info from init file itself */
     411           0 :                 if (read_init_file(mem_ctx, name, &init_info)) {
     412           0 :                         description = talloc_strdup(mem_ctx,
     413           0 :                                                     init_info->description);
     414             :                 } else {
     415           0 :                         description = talloc_strdup(mem_ctx,
     416             :                                                     "External Unix Service");
     417             :                 }
     418             :         }
     419             : 
     420         892 :         if (ipath == NULL || dname == NULL || description == NULL) {
     421             :                 goto done;
     422             :         }
     423             : 
     424         300 :         status = dcerpc_winreg_set_sz(mem_ctx,
     425             :                                       h,
     426             :                                       &key_hnd,
     427             :                                       "DisplayName",
     428             :                                       dname,
     429             :                                       &result);
     430         300 :         if (!NT_STATUS_IS_OK(status)) {
     431           0 :                 DEBUG(0, ("svcctl_init_winreg_keys: Could not create value: %s\n",
     432             :                           nt_errstr(status)));
     433           0 :                 goto done;
     434             :         }
     435         300 :         if (!W_ERROR_IS_OK(result)) {
     436           0 :                 DEBUG(0, ("svcctl_init_winreg_keys: Could not create value: %s\n",
     437             :                           win_errstr(result)));
     438           0 :                 goto done;
     439             :         }
     440             : 
     441         300 :         status = dcerpc_winreg_set_sz(mem_ctx,
     442             :                                       h,
     443             :                                       &key_hnd,
     444             :                                       "ImagePath",
     445             :                                       ipath,
     446             :                                       &result);
     447         300 :         if (!NT_STATUS_IS_OK(status)) {
     448           0 :                 DEBUG(0, ("svcctl_init_winreg_keys: Could not create value: %s\n",
     449             :                           nt_errstr(status)));
     450           0 :                 goto done;
     451             :         }
     452         300 :         if (!W_ERROR_IS_OK(result)) {
     453           0 :                 DEBUG(0, ("svcctl_init_winreg_keys: Could not create value: %s\n",
     454             :                           win_errstr(result)));
     455           0 :                 goto done;
     456             :         }
     457             : 
     458         300 :         status = dcerpc_winreg_set_sz(mem_ctx,
     459             :                                       h,
     460             :                                       &key_hnd,
     461             :                                       "Description",
     462             :                                       description,
     463             :                                       &result);
     464         300 :         if (!NT_STATUS_IS_OK(status)) {
     465           0 :                 DEBUG(0, ("svcctl_init_winreg_keys: Could not create value: %s\n",
     466             :                           nt_errstr(status)));
     467           0 :                 goto done;
     468             :         }
     469         300 :         if (!W_ERROR_IS_OK(result)) {
     470           0 :                 DEBUG(0, ("svcctl_init_winreg_keys: Could not create value: %s\n",
     471             :                           win_errstr(result)));
     472           0 :                 goto done;
     473             :         }
     474             : 
     475         300 :         sd = svcctl_gen_service_sd(mem_ctx);
     476         300 :         if (sd == NULL) {
     477           0 :                 DEBUG(0, ("add_new_svc_name: Failed to create default "
     478             :                           "sec_desc!\n"));
     479           0 :                 goto done;
     480             :         }
     481             : 
     482         300 :         if (is_valid_policy_hnd(&key_hnd)) {
     483         300 :                 dcerpc_winreg_CloseKey(h, mem_ctx, &key_hnd, &result);
     484             :         }
     485         300 :         ZERO_STRUCT(key_hnd);
     486             : 
     487         300 :         ZERO_STRUCT(wkey);
     488         300 :         wkey.name = talloc_asprintf(mem_ctx, "%s\\%s\\Security", key, name);
     489         300 :         if (wkey.name == NULL) {
     490           0 :                 result = WERR_NOT_ENOUGH_MEMORY;
     491           0 :                 goto done;
     492             :         }
     493             : 
     494         300 :         ZERO_STRUCT(wkeyclass);
     495         300 :         wkeyclass.name = "";
     496             : 
     497         300 :         status = dcerpc_winreg_CreateKey(h,
     498             :                                          mem_ctx,
     499             :                                          hive_hnd,
     500             :                                          wkey,
     501             :                                          wkeyclass,
     502             :                                          0,
     503             :                                          access_mask,
     504             :                                          NULL,
     505             :                                          &key_hnd,
     506             :                                          &action,
     507             :                                          &result);
     508         300 :         if (!NT_STATUS_IS_OK(status)) {
     509           0 :                 DEBUG(0, ("svcctl_init_winreg_keys: Could not create key %s: %s\n",
     510             :                         wkey.name, nt_errstr(status)));
     511           0 :                 goto done;
     512             :         }
     513         300 :         if (!W_ERROR_IS_OK(result)) {
     514           0 :                 DEBUG(0, ("svcctl_init_winreg_keys: Could not create key %s: %s\n",
     515             :                         wkey.name, win_errstr(result)));
     516           0 :                 goto done;
     517             :         }
     518             : 
     519         300 :         status = dcerpc_winreg_set_sd(mem_ctx,
     520             :                                       h,
     521             :                                       &key_hnd,
     522             :                                       "Security",
     523             :                                       sd,
     524             :                                       &result);
     525         300 :         if (!NT_STATUS_IS_OK(status)) {
     526           0 :                 DEBUG(0, ("svcctl_init_winreg_keys: Could not create value: %s\n",
     527             :                           nt_errstr(status)));
     528           0 :                 goto done;
     529             :         }
     530         300 :         if (!W_ERROR_IS_OK(result)) {
     531           0 :                 DEBUG(0, ("svcctl_init_winreg_keys: Could not create value: %s\n",
     532             :                           win_errstr(result)));
     533           0 :                 goto done;
     534             :         }
     535             : 
     536         292 :         ok = true;
     537         300 : done:
     538         300 :         if (is_valid_policy_hnd(&key_hnd)) {
     539         300 :                 dcerpc_winreg_CloseKey(h, mem_ctx, &key_hnd, &result);
     540             :         }
     541             : 
     542         300 :         return ok;
     543             : }
     544             : 
     545          75 : bool svcctl_init_winreg(struct messaging_context *msg_ctx)
     546             : {
     547          75 :         struct dcerpc_binding_handle *h = NULL;
     548          75 :         uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
     549             :         struct policy_handle hive_hnd, key_hnd;
     550          75 :         const char **service_list = lp_svcctl_list();
     551          75 :         const char **subkeys = NULL;
     552          75 :         uint32_t num_subkeys = 0;
     553          75 :         char *key = NULL;
     554             :         uint32_t i;
     555             :         NTSTATUS status;
     556          75 :         WERROR result = WERR_OK;
     557          75 :         bool ok = false;
     558             :         TALLOC_CTX *tmp_ctx;
     559             : 
     560          75 :         tmp_ctx = talloc_stackframe();
     561          75 :         if (tmp_ctx == NULL) {
     562           0 :                 return false;
     563             :         }
     564             : 
     565          75 :         DEBUG(3, ("Initialise the svcctl registry keys if needed.\n"));
     566             : 
     567          75 :         ZERO_STRUCT(hive_hnd);
     568          75 :         ZERO_STRUCT(key_hnd);
     569             : 
     570          75 :         key = talloc_strdup(tmp_ctx, TOP_LEVEL_SERVICES_KEY);
     571          75 :         if (key == NULL) {
     572           0 :                 goto done;
     573             :         }
     574             : 
     575          75 :         result = regdb_open();
     576          75 :         if (!W_ERROR_IS_OK(result)) {
     577           0 :                 DEBUG(10, ("regdb_open failed: %s\n",
     578             :                            win_errstr(result)));
     579           0 :                 goto done;
     580             :         }
     581          75 :         result = regdb_transaction_start();
     582          75 :         if (!W_ERROR_IS_OK(result)) {
     583           0 :                 DEBUG(10, ("regdb_transaction_start failed: %s\n",
     584             :                            win_errstr(result)));
     585           0 :                 goto done;
     586             :         }
     587             : 
     588          75 :         status = dcerpc_winreg_int_hklm_openkey(tmp_ctx,
     589             :                                                 get_session_info_system(),
     590             :                                                 msg_ctx,
     591             :                                                 &h,
     592             :                                                 key,
     593             :                                                 false,
     594             :                                                 access_mask,
     595             :                                                 &hive_hnd,
     596             :                                                 &key_hnd,
     597             :                                                 &result);
     598          75 :         if (!NT_STATUS_IS_OK(status)) {
     599           0 :                 DEBUG(0, ("svcctl_init_winreg: Could not open %s - %s\n",
     600             :                           key, nt_errstr(status)));
     601           0 :                 goto done;
     602             :         }
     603          75 :         if (!W_ERROR_IS_OK(result)) {
     604           0 :                 DEBUG(0, ("svcctl_init_winreg: Could not open %s - %s\n",
     605             :                           key, win_errstr(result)));
     606           0 :                 goto done;
     607             :         }
     608             : 
     609             :         /* get all subkeys */
     610          75 :         status = dcerpc_winreg_enum_keys(tmp_ctx,
     611             :                                          h,
     612             :                                          &key_hnd,
     613             :                                          &num_subkeys,
     614             :                                          &subkeys,
     615             :                                          &result);
     616          75 :         if (!NT_STATUS_IS_OK(status)) {
     617           0 :                 DEBUG(0, ("svcctl_init_winreg: Could enum keys at %s - %s\n",
     618             :                           key, nt_errstr(status)));
     619           0 :                 goto done;
     620             :         }
     621          75 :         if (!W_ERROR_IS_OK(result)) {
     622           0 :                 DEBUG(0, ("svcctl_init_winreg: Could enum keys at %s - %s\n",
     623             :                           key, win_errstr(result)));
     624           0 :                 goto done;
     625             :         }
     626             : 
     627         373 :         for (i = 0; builtin_svcs[i].servicename != NULL; i++) {
     628             :                 uint32_t j;
     629         292 :                 bool skip = false;
     630             : 
     631        1504 :                 for (j = 0; j < num_subkeys; j++) {
     632        1212 :                         if (strequal(subkeys[i], builtin_svcs[i].servicename)) {
     633           0 :                                 skip = true;
     634             :                         }
     635             :                 }
     636             : 
     637         300 :                 if (skip) {
     638           0 :                         continue;
     639             :                 }
     640             : 
     641         300 :                 ok = svcctl_add_service(tmp_ctx,
     642             :                                         h,
     643             :                                         &hive_hnd,
     644             :                                         key,
     645             :                                         access_mask,
     646             :                                         builtin_svcs[i].servicename);
     647         300 :                 if (!ok) {
     648           0 :                         goto done;
     649             :                 }
     650             :         }
     651             : 
     652          73 :         for (i = 0; service_list && service_list[i]; i++) {
     653             :                 uint32_t j;
     654           0 :                 bool skip = false;
     655             : 
     656           0 :                 for (j = 0; j < num_subkeys; j++) {
     657           0 :                         if (strequal(subkeys[i], service_list[i])) {
     658           0 :                                 skip = true;
     659             :                         }
     660             :                 }
     661             : 
     662           0 :                 if (skip) {
     663           0 :                         continue;
     664             :                 }
     665             : 
     666           0 :                 ok = svcctl_add_service(tmp_ctx,
     667             :                                         h,
     668             :                                         &hive_hnd,
     669             :                                         key,
     670             :                                         access_mask,
     671           0 :                                         service_list[i]);
     672           0 :                 if (is_valid_policy_hnd(&key_hnd)) {
     673           0 :                         dcerpc_winreg_CloseKey(h, tmp_ctx, &key_hnd, &result);
     674             :                 }
     675           0 :                 ZERO_STRUCT(key_hnd);
     676             : 
     677           0 :                 if (!ok) {
     678           0 :                         goto done;
     679             :                 }
     680             :         }
     681             : 
     682          75 : done:
     683          75 :         if (is_valid_policy_hnd(&key_hnd)) {
     684          75 :                 dcerpc_winreg_CloseKey(h, tmp_ctx, &key_hnd, &result);
     685             :         }
     686             : 
     687          75 :         if (ok) {
     688          75 :                 result = regdb_transaction_commit();
     689          75 :                 if (!W_ERROR_IS_OK(result)) {
     690           0 :                         DEBUG(10, ("regdb_transaction_commit failed: %s\n",
     691             :                                    win_errstr(result)));
     692             :                 }
     693             :         } else {
     694           0 :                 result = regdb_transaction_cancel();
     695           0 :                 if (!W_ERROR_IS_OK(result)) {
     696           0 :                         DEBUG(10, ("regdb_transaction_cancel failed: %s\n",
     697             :                                    win_errstr(result)));
     698             :                 }
     699             :         }
     700          75 :         regdb_close();
     701          75 :         talloc_free(tmp_ctx);
     702          75 :         return ok;
     703             : }
     704             : 
     705             : /* vim: set ts=8 sw=8 noet cindent syntax=c.doxygen: */

Generated by: LCOV version 1.13