RIP BOOL. Convert BOOL -> bool. I found a few interesting
[nivanova/samba-autobuild/.git] / source3 / services / services_db.c
index 5c87225f57304e73c592d88d57dc2a8c329355b9..ccb69d76e41160d43f946af312fbea59ce594e5c 100644 (file)
@@ -8,7 +8,7 @@
  *  
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
+ *  the Free Software Foundation; either version 3 of the License, or
  *  (at your option) any later version.
  *  
  *  This program is distributed in the hope that it will be useful,
@@ -17,8 +17,7 @@
  *  GNU General Public License for more details.
  *  
  *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
 #include "includes.h"
@@ -35,43 +34,51 @@ struct service_display_info {
 };
 
 struct service_display_info builtin_svcs[] = {  
-  { "Spooler",       "smbd", "Print Spooler",
-       "Internal service for spooling files to print devices" },
-  { "NETLOGON",              "smbd", "Net Logon",
-       "File service providing access to policy and profile data" },
-  { "RemoteRegistry", "smbd", "Remote Registry Service",
-       "Internal service providing remote access to the Samba registry" },
-  { "WINS",           "nmbd", "Windows Internet Name Service (WINS)",
-       "Internal service providing a NetBIOS point-to-point name server" },
+  { "Spooler",       "smbd",   "Print Spooler", "Internal service for spooling files to print devices" },
+  { "NETLOGON",              "smbd",   "Net Logon", "File service providing access to policy and profile data (not remotely manageable)" },
+  { "RemoteRegistry", "smbd",  "Remote Registry Service", "Internal service providing remote access to "
+                               "the Samba registry" },
+  { "WINS",           "nmbd",  "Windows Internet Name Service (WINS)", "Internal service providing a "
+                               "NetBIOS point-to-point name server (not remotely manageable)" },
   { NULL, NULL, NULL, NULL }
 };
 
 struct service_display_info common_unix_svcs[] = {  
-  { "cups",          NULL, "Common Unix Printing System", NULL },
-  { "postfix",       NULL, "Internet Mail Service", NULL },
-  { "sendmail",      NULL, "Internet Mail Service", NULL },
-  { "portmap",       NULL, "TCP Port to RPC PortMapper", NULL },
-  { "xinetd",        NULL, "Internet Meta-Daemon", NULL },
-  { "inet",          NULL, "Internet Meta-Daemon", NULL },
-  { "xntpd",         NULL, "Network Time Service", NULL },
-  { "ntpd",          NULL, "Network Time Service", NULL },
-  { "lpd",           NULL, "BSD Print Spooler", NULL },
-  { "nfsserver",     NULL, "Network File Service", NULL },
-  { "cron",          NULL, "Scheduling Service", NULL },
-  { "at",            NULL, "Scheduling Service", NULL },
-  { "nscd",          NULL, "Name Service Cache Daemon", NULL },
-  { "slapd",         NULL, "LDAP Directory Service", NULL },
-  { "ldap",          NULL, "LDAP DIrectory Service", NULL },
-  { "ypbind",        NULL, "NIS Directory Service", NULL },
-  { "courier-imap",  NULL, "IMAP4 Mail Service", NULL },
-  { "courier-pop3",  NULL, "POP3 Mail Service", NULL },
-  { "named",         NULL, "Domain Name Service", NULL },
-  { "bind",          NULL, "Domain Name Service", NULL },
-  { "httpd",         NULL, "HTTP Server", NULL },
-  { "apache",        NULL, "HTTP Server", NULL },
-  { "autofs",        NULL, "Automounter", NULL },
-  { "squid",         NULL, "Web Cache Proxy ", NULL },
+  { "cups",          NULL, "Common Unix Printing System","Provides unified printing support for all operating systems" },
+  { "postfix",       NULL, "Internet Mail Service",    "Provides support for sending and receiving electonic mail" },
+  { "sendmail",      NULL, "Internet Mail Service",    "Provides support for sending and receiving electonic mail" },
+  { "portmap",       NULL, "TCP Port to RPC PortMapper",NULL },
+  { "xinetd",        NULL, "Internet Meta-Daemon",     NULL },
+  { "inet",          NULL, "Internet Meta-Daemon",     NULL },
+  { "xntpd",         NULL, "Network Time Service",     NULL },
+  { "ntpd",          NULL, "Network Time Service",     NULL },
+  { "lpd",           NULL, "BSD Print Spooler",        NULL },
+  { "nfsserver",     NULL, "Network File Service",     NULL },
+  { "cron",          NULL, "Scheduling Service",       NULL },
+  { "at",            NULL, "Scheduling Service",       NULL },
+  { "nscd",          NULL, "Name Service Cache Daemon",        NULL },
+  { "slapd",         NULL, "LDAP Directory Service",   NULL },
+  { "ldap",          NULL, "LDAP DIrectory Service",   NULL },
+  { "ypbind",        NULL, "NIS Directory Service",    NULL },
+  { "courier-imap",  NULL, "IMAP4 Mail Service",       NULL },
+  { "courier-pop3",  NULL, "POP3 Mail Service",        NULL },
+  { "named",         NULL, "Domain Name Service",      NULL },
+  { "bind",          NULL, "Domain Name Service",      NULL },
+  { "httpd",         NULL, "HTTP Server",              NULL },
+  { "apache",        NULL, "HTTP Server",              "Provides s highly scalable and flexible web server "
+                                                       "capable of implementing various protocols incluing "
+                                                       "but not limited to HTTP" },
+  { "autofs",        NULL, "Automounter",              NULL },
+  { "squid",         NULL, "Web Cache Proxy ",         NULL },
   { "perfcountd",    NULL, "Performance Monitoring Daemon", NULL },
+  { "pgsql",        NULL, "PgSQL Database Server",     "Provides service for SQL database from Postgresql.org" },
+  { "arpwatch",             NULL, "ARP Tables watcher",        "Provides service for monitoring ARP tables for changes" },
+  { "dhcpd",        NULL, "DHCP Server",               "Provides service for dynamic host configuration and IP assignment" },
+  { "nwserv",       NULL, "NetWare Server Emulator",   "Provides service for emulating Novell NetWare 3.12 server" },
+  { "proftpd",      NULL, "Professional FTP Server",   "Provides high configurable service for FTP connection and "
+                                                       "file transferring" },
+  { "ssh2",         NULL, "SSH Secure Shell",          "Provides service for secure connection for remote administration" },
+  { "sshd",         NULL, "SSH Secure Shell",          "Provides service for secure connection for remote administration" },
   { NULL, NULL, NULL, NULL }
 };
 
@@ -141,7 +148,7 @@ static char *get_common_service_dispname( const char *servicename )
 
 static char* cleanup_string( const char *string )
 {
-       static pstring clean;
+       pstring clean;
        char *begin, *end;
 
        pstrcpy( clean, string );
@@ -152,7 +159,7 @@ static char* cleanup_string( const char *string )
        while ( isspace(*begin) )
                begin++;
 
-       if ( !begin )
+       if ( *begin == '\0' )
                return NULL;
                        
        /* trim any trailing whitespace or carriage returns.
@@ -165,13 +172,13 @@ static char* cleanup_string( const char *string )
                end--;
        }
 
-       return begin;
+       return talloc_strdup(talloc_tos(), begin);
 }
 
 /********************************************************************
 ********************************************************************/
 
-static BOOL read_init_file( const char *servicename, struct rcinit_file_information **service_info )
+static bool read_init_file( const char *servicename, struct rcinit_file_information **service_info )
 {
        struct rcinit_file_information *info;
        pstring filepath, str;
@@ -304,7 +311,8 @@ static void add_new_svc_name( REGISTRY_KEY *key_parent, REGSUBKEY_CTR *subkeys,
        REGVAL_CTR *values;
        REGSUBKEY_CTR *svc_subkeys;
        SEC_DESC *sd;
-       prs_struct ps;
+       DATA_BLOB sd_blob;
+       NTSTATUS status;
 
        /* add to the list and create the subkey path */
 
@@ -314,8 +322,8 @@ static void add_new_svc_name( REGISTRY_KEY *key_parent, REGSUBKEY_CTR *subkeys,
        /* open the new service key */
 
        pstr_sprintf( path, "%s\\%s", KEY_SERVICES, name );
-       wresult = regkey_open_internal( &key_service, path, get_root_nt_token(), 
-               REG_KEY_ALL );
+       wresult = regkey_open_internal( NULL, &key_service, path,
+                                       get_root_nt_token(), REG_KEY_ALL );
        if ( !W_ERROR_IS_OK(wresult) ) {
                DEBUG(0,("add_new_svc_name: key lookup failed! [%s] (%s)\n", 
                        path, dos_errstr(wresult)));
@@ -326,7 +334,7 @@ static void add_new_svc_name( REGISTRY_KEY *key_parent, REGSUBKEY_CTR *subkeys,
 
        if ( !(svc_subkeys = TALLOC_ZERO_P( key_service, REGSUBKEY_CTR )) ) {
                DEBUG(0,("add_new_svc_name: talloc() failed!\n"));
-               regkey_close_internal( key_service );
+               TALLOC_FREE( key_service );
                return;
        }
        
@@ -338,7 +346,7 @@ static void add_new_svc_name( REGISTRY_KEY *key_parent, REGSUBKEY_CTR *subkeys,
        
        if ( !(values = TALLOC_ZERO_P( key_service, REGVAL_CTR )) ) {
                DEBUG(0,("add_new_svc_name: talloc() failed!\n"));
-               regkey_close_internal( key_service );
+               TALLOC_FREE( key_service );
                return;
        }
 
@@ -347,46 +355,46 @@ static void add_new_svc_name( REGISTRY_KEY *key_parent, REGSUBKEY_CTR *subkeys,
 
        /* cleanup the service key*/
 
-       regkey_close_internal( key_service );
+       TALLOC_FREE( key_service );
 
        /* now add the security descriptor */
 
        pstr_sprintf( path, "%s\\%s\\%s", KEY_SERVICES, name, "Security" );
-       wresult = regkey_open_internal( &key_secdesc, path, get_root_nt_token(), 
-               REG_KEY_ALL );
+       wresult = regkey_open_internal( NULL, &key_secdesc, path,
+                                       get_root_nt_token(), REG_KEY_ALL );
        if ( !W_ERROR_IS_OK(wresult) ) {
                DEBUG(0,("add_new_svc_name: key lookup failed! [%s] (%s)\n", 
                        path, dos_errstr(wresult)));
-               regkey_close_internal( key_secdesc );
+               TALLOC_FREE( key_secdesc );
                return;
        }
 
        if ( !(values = TALLOC_ZERO_P( key_secdesc, REGVAL_CTR )) ) {
                DEBUG(0,("add_new_svc_name: talloc() failed!\n"));
-               regkey_close_internal( key_secdesc );
+               TALLOC_FREE( key_secdesc );
                return;
        }
 
        if ( !(sd = construct_service_sd(key_secdesc)) ) {
                DEBUG(0,("add_new_svc_name: Failed to create default sec_desc!\n"));
-               regkey_close_internal( key_secdesc );
+               TALLOC_FREE( key_secdesc );
                return;
        }
-       
-       /* stream the printer security descriptor */
-       
-       prs_init( &ps, RPC_MAX_PDU_FRAG_LEN, key_secdesc, MARSHALL);
-       
-       if ( sec_io_desc("sec_desc", &sd, &ps, 0 ) ) {
-               uint32 offset = prs_offset( &ps );
-               regval_ctr_addvalue( values, "Security", REG_BINARY, prs_data_p(&ps), offset );
-               store_reg_values( key_secdesc, values );
+
+       status = marshall_sec_desc(key_secdesc, sd, &sd_blob.data,
+                                  &sd_blob.length);
+       if (!NT_STATUS_IS_OK(status)) {
+               DEBUG(0, ("marshall_sec_desc failed: %s\n",
+                         nt_errstr(status)));
+               TALLOC_FREE(key_secdesc);
+               return;
        }
        
-       /* finally cleanup the Security key */
+       regval_ctr_addvalue(values, "Security", REG_BINARY,
+                           (const char *)sd_blob.data, sd_blob.length);
+       store_reg_values( key_secdesc, values );
        
-       prs_mem_free( &ps );
-       regkey_close_internal( key_secdesc );
+       TALLOC_FREE( key_secdesc );
 
        return;
 }
@@ -404,11 +412,11 @@ void svcctl_init_keys( void )
        
        /* bad mojo here if the lookup failed.  Should not happen */
        
-       wresult = regkey_open_internal( &key, KEY_SERVICES, get_root_nt_token(), 
-               REG_KEY_ALL );
+       wresult = regkey_open_internal( NULL, &key, KEY_SERVICES,
+                                       get_root_nt_token(), REG_KEY_ALL );
 
        if ( !W_ERROR_IS_OK(wresult) ) {
-               DEBUG(0,("init_services_keys: key lookup failed! (%s)\n", 
+               DEBUG(0,("svcctl_init_keys: key lookup failed! (%s)\n", 
                        dos_errstr(wresult)));
                return;
        }
@@ -416,8 +424,8 @@ void svcctl_init_keys( void )
        /* lookup the available subkeys */      
        
        if ( !(subkeys = TALLOC_ZERO_P( key, REGSUBKEY_CTR )) ) {
-               DEBUG(0,("init_services_keys: talloc() failed!\n"));
-               regkey_close_internal( key );
+               DEBUG(0,("svcctl_init_keys: talloc() failed!\n"));
+               TALLOC_FREE( key );
                return;
        }
        
@@ -428,7 +436,7 @@ void svcctl_init_keys( void )
        for ( i=0; builtin_svcs[i].servicename; i++ )
                add_new_svc_name( key, subkeys, builtin_svcs[i].servicename );
                
-       for ( i=0; service_list[i]; i++ ) {
+       for ( i=0; service_list && service_list[i]; i++ ) {
        
                /* only add new services */
                if ( regsubkey_ctr_key_exists( subkeys, service_list[i] ) )
@@ -439,7 +447,7 @@ void svcctl_init_keys( void )
                add_new_svc_name( key, subkeys, service_list[i] );
        }
 
-       regkey_close_internal( key );
+       TALLOC_FREE( key );
 
        /* initialize the control hooks */
 
@@ -457,18 +465,18 @@ void svcctl_init_keys( void )
 SEC_DESC* svcctl_get_secdesc( TALLOC_CTX *ctx, const char *name, NT_USER_TOKEN *token )
 {
        REGISTRY_KEY *key;
-       prs_struct ps;
        REGVAL_CTR *values;
        REGISTRY_VALUE *val;
-       SEC_DESC *sd = NULL;
        SEC_DESC *ret_sd = NULL;
        pstring path;
        WERROR wresult;
+       NTSTATUS status;
        
        /* now add the security descriptor */
 
        pstr_sprintf( path, "%s\\%s\\%s", KEY_SERVICES, name, "Security" );
-       wresult = regkey_open_internal( &key, path, token, REG_KEY_ALL );
+       wresult = regkey_open_internal( NULL, &key, path, token,
+                                       REG_KEY_ALL );
        if ( !W_ERROR_IS_OK(wresult) ) {
                DEBUG(0,("svcctl_get_secdesc: key lookup failed! [%s] (%s)\n", 
                        path, dos_errstr(wresult)));
@@ -477,38 +485,79 @@ SEC_DESC* svcctl_get_secdesc( TALLOC_CTX *ctx, const char *name, NT_USER_TOKEN *
 
        if ( !(values = TALLOC_ZERO_P( key, REGVAL_CTR )) ) {
                DEBUG(0,("add_new_svc_name: talloc() failed!\n"));
-               regkey_close_internal( key );
+               TALLOC_FREE( key );
                return NULL;
        }
 
        fetch_reg_values( key, values );
+
+       TALLOC_FREE(key);
        
        if ( !(val = regval_ctr_getvalue( values, "Security" )) ) {
                DEBUG(6,("svcctl_get_secdesc: constructing default secdesc for service [%s]\n", 
                        name));
-               regkey_close_internal( key );
                return construct_service_sd( ctx );
        }
        
 
+       /* stream the service security descriptor */
+
+       status = unmarshall_sec_desc(ctx, regval_data_p(val),
+                                    regval_size(val), &ret_sd);
+
+       if (!NT_STATUS_IS_OK(status)) {
+               return construct_service_sd( ctx );
+       }
+
+       return ret_sd;
+}
+
+/********************************************************************
+ Wrapper to make storing a Service sd easier
+********************************************************************/
+
+bool svcctl_set_secdesc( TALLOC_CTX *ctx, const char *name, SEC_DESC *sec_desc, NT_USER_TOKEN *token )
+{
+       REGISTRY_KEY *key;
+       WERROR wresult;
+       pstring path;
+       REGVAL_CTR *values;
+       prs_struct ps;
+       bool ret = False;
+       
+       /* now add the security descriptor */
+
+       pstr_sprintf( path, "%s\\%s\\%s", KEY_SERVICES, name, "Security" );
+       wresult = regkey_open_internal( NULL, &key, path, token,
+                                       REG_KEY_ALL );
+       if ( !W_ERROR_IS_OK(wresult) ) {
+               DEBUG(0,("svcctl_get_secdesc: key lookup failed! [%s] (%s)\n", 
+                       path, dos_errstr(wresult)));
+               return False;
+       }
+
+       if ( !(values = TALLOC_ZERO_P( key, REGVAL_CTR )) ) {
+               DEBUG(0,("add_new_svc_name: talloc() failed!\n"));
+               TALLOC_FREE( key );
+               return False;
+       }
+       
        /* stream the printer security descriptor */
        
-       prs_init( &ps, 0, key, UNMARSHALL);
-       prs_give_memory( &ps, (char *)regval_data_p(val), regval_size(val), False );
+       prs_init( &ps, RPC_MAX_PDU_FRAG_LEN, key, MARSHALL);
        
-       if ( !sec_io_desc("sec_desc", &sd, &ps, 0 ) ) {
-               regkey_close_internal( key );
-               return construct_service_sd( ctx );
+       if ( sec_io_desc("sec_desc", &sec_desc, &ps, 0 ) ) {
+               uint32 offset = prs_offset( &ps );
+               regval_ctr_addvalue( values, "Security", REG_BINARY, prs_data_p(&ps), offset );
+               ret = store_reg_values( key, values );
        }
        
-       ret_sd = dup_sec_desc( ctx, sd );
-       
-       /* finally cleanup the Security key */
+       /* cleanup */
        
        prs_mem_free( &ps );
-       regkey_close_internal( key );
+       TALLOC_FREE( key);
 
-       return ret_sd;
+       return ret;
 }
 
 /********************************************************************
@@ -526,7 +575,8 @@ char* svcctl_lookup_dispname( const char *name, NT_USER_TOKEN *token )
        /* now add the security descriptor */
 
        pstr_sprintf( path, "%s\\%s", KEY_SERVICES, name );
-       wresult = regkey_open_internal( &key, path, token, REG_KEY_READ );
+       wresult = regkey_open_internal( NULL, &key, path, token,
+                                       REG_KEY_READ );
        if ( !W_ERROR_IS_OK(wresult) ) {
                DEBUG(0,("svcctl_lookup_dispname: key lookup failed! [%s] (%s)\n", 
                        path, dos_errstr(wresult)));
@@ -535,7 +585,7 @@ char* svcctl_lookup_dispname( const char *name, NT_USER_TOKEN *token )
 
        if ( !(values = TALLOC_ZERO_P( key, REGVAL_CTR )) ) {
                DEBUG(0,("svcctl_lookup_dispname: talloc() failed!\n"));
-               regkey_close_internal( key );
+               TALLOC_FREE( key );
                goto fail;
        }
 
@@ -546,13 +596,13 @@ char* svcctl_lookup_dispname( const char *name, NT_USER_TOKEN *token )
 
        rpcstr_pull( display_name, regval_data_p(val), sizeof(display_name), regval_size(val), 0 );
 
-       regkey_close_internal( key );
+       TALLOC_FREE( key );
        
        return display_name;
 
 fail:
        /* default to returning the service name */
-       regkey_close_internal( key );
+       TALLOC_FREE( key );
        fstrcpy( display_name, name );
        return display_name;
 }
@@ -572,7 +622,8 @@ char* svcctl_lookup_description( const char *name, NT_USER_TOKEN *token )
        /* now add the security descriptor */
 
        pstr_sprintf( path, "%s\\%s", KEY_SERVICES, name );
-       wresult = regkey_open_internal( &key, path, token, REG_KEY_READ );
+       wresult = regkey_open_internal( NULL, &key, path, token,
+                                       REG_KEY_READ );
        if ( !W_ERROR_IS_OK(wresult) ) {
                DEBUG(0,("svcctl_lookup_dispname: key lookup failed! [%s] (%s)\n", 
                        path, dos_errstr(wresult)));
@@ -581,7 +632,7 @@ char* svcctl_lookup_description( const char *name, NT_USER_TOKEN *token )
 
        if ( !(values = TALLOC_ZERO_P( key, REGVAL_CTR )) ) {
                DEBUG(0,("svcctl_lookup_dispname: talloc() failed!\n"));
-               regkey_close_internal( key );
+               TALLOC_FREE( key );
                return NULL;
        }
 
@@ -592,7 +643,7 @@ char* svcctl_lookup_description( const char *name, NT_USER_TOKEN *token )
        else
                rpcstr_pull( description, regval_data_p(val), sizeof(description), regval_size(val), 0 );
 
-       regkey_close_internal( key );
+       TALLOC_FREE( key );
        
        return description;
 }
@@ -611,7 +662,8 @@ REGVAL_CTR* svcctl_fetch_regvalues( const char *name, NT_USER_TOKEN *token )
        /* now add the security descriptor */
 
        pstr_sprintf( path, "%s\\%s", KEY_SERVICES, name );
-       wresult = regkey_open_internal( &key, path, token, REG_KEY_READ );
+       wresult = regkey_open_internal( NULL, &key, path, token,
+                                       REG_KEY_READ );
        if ( !W_ERROR_IS_OK(wresult) ) {
                DEBUG(0,("svcctl_fetch_regvalues: key lookup failed! [%s] (%s)\n", 
                        path, dos_errstr(wresult)));
@@ -620,13 +672,13 @@ REGVAL_CTR* svcctl_fetch_regvalues( const char *name, NT_USER_TOKEN *token )
 
        if ( !(values = TALLOC_ZERO_P( NULL, REGVAL_CTR )) ) {
                DEBUG(0,("svcctl_fetch_regvalues: talloc() failed!\n"));
-               regkey_close_internal( key );
+               TALLOC_FREE( key );
                return NULL;
        }
        
        fetch_reg_values( key, values );
 
-       regkey_close_internal( key );
+       TALLOC_FREE( key );
        
        return values;
 }