diff options
Diffstat (limited to 'source3/rpc_parse/parse_svcctl.c')
-rw-r--r-- | source3/rpc_parse/parse_svcctl.c | 305 |
1 files changed, 253 insertions, 52 deletions
diff --git a/source3/rpc_parse/parse_svcctl.c b/source3/rpc_parse/parse_svcctl.c index b86ca23df15..e1a7ad84273 100644 --- a/source3/rpc_parse/parse_svcctl.c +++ b/source3/rpc_parse/parse_svcctl.c @@ -100,40 +100,48 @@ static BOOL svcctl_io_service_config( const char *desc, SERVICE_CONFIG *config, return True; } + /******************************************************************* ********************************************************************/ -BOOL svcctl_io_service_description( const char *desc, UNISTR2 *svcdesc, prs_struct *ps, int depth ) +BOOL svcctl_io_enum_services_status( const char *desc, ENUM_SERVICES_STATUS *enum_status, RPC_BUFFER *buffer, int depth ) { - - prs_debug(ps, depth, desc, "svcctl_io_service_description"); + prs_struct *ps=&buffer->prs; + + prs_debug(ps, depth, desc, "svcctl_io_enum_services_status"); depth++; - - if (!prs_io_unistr2("", ps, depth, svcdesc)) + + if ( !smb_io_relstr("servicename", buffer, depth, &enum_status->servicename) ) + return False; + if ( !smb_io_relstr("displayname", buffer, depth, &enum_status->displayname) ) return False; + if ( !svcctl_io_service_status("svc_status", &enum_status->status, ps, depth) ) + return False; + return True; } - /******************************************************************* ********************************************************************/ -BOOL svcctl_io_enum_services_status( const char *desc, ENUM_SERVICES_STATUS *enum_status, RPC_BUFFER *buffer, int depth ) +BOOL svcctl_io_service_status_process( const char *desc, SERVICE_STATUS_PROCESS *status, RPC_BUFFER *buffer, int depth ) { prs_struct *ps=&buffer->prs; - - prs_debug(ps, depth, desc, "svcctl_io_enum_services_status"); + + prs_debug(ps, depth, desc, "svcctl_io_service_status_process"); depth++; - - if ( !smb_io_relstr("servicename", buffer, depth, &enum_status->servicename) ) + + if ( !svcctl_io_service_status("status", &status->status, ps, depth) ) return False; - if ( !smb_io_relstr("displayname", buffer, depth, &enum_status->displayname) ) + if(!prs_align(ps)) return False; - if ( !svcctl_io_service_status("svc_status", &enum_status->status, ps, depth) ) + if(!prs_uint32("process_id", ps, depth, &status->process_id)) return False; - + if(!prs_uint32("service_flags", ps, depth, &status->service_flags)) + return False; + return True; } @@ -151,6 +159,45 @@ uint32 svcctl_sizeof_enum_services_status( ENUM_SERVICES_STATUS *status ) return size; } +/******************************************************************** +********************************************************************/ + +static uint32 sizeof_unistr2( UNISTR2 *string ) +{ + uint32 size = 0; + + if ( !string ) + return 0; + + size = sizeof(uint32) * 3; /* length fields */ + size += 2 * string->uni_max_len; /* string data */ + size += size % 4; /* alignment */ + + return size; +} + +/******************************************************************** +********************************************************************/ + +uint32 svcctl_sizeof_service_config( SERVICE_CONFIG *config ) +{ + uint32 size = 0; + + size = sizeof(uint32) * 4; /* static uint32 fields */ + + /* now add the UNISTR2 + pointer sizes */ + + size += sizeof(uint32) * sizeof_unistr2(config->executablepath); + size += sizeof(uint32) * sizeof_unistr2(config->loadordergroup); + size += sizeof(uint32) * sizeof_unistr2(config->dependencies); + size += sizeof(uint32) * sizeof_unistr2(config->startname); + size += sizeof(uint32) * sizeof_unistr2(config->displayname); + + return size; +} + + + /******************************************************************* ********************************************************************/ @@ -694,7 +741,7 @@ BOOL svcctl_io_q_query_service_config2(const char *desc, SVCCTL_Q_QUERY_SERVICE_ if(!smb_io_pol_hnd("service_pol", &q_u->handle, ps, depth)) return False; - if(!prs_uint32("info_level", ps, depth, &q_u->info_level)) + if(!prs_uint32("level", ps, depth, &q_u->level)) return False; if(!prs_uint32("buffer_size", ps, depth, &q_u->buffer_size)) @@ -705,39 +752,148 @@ BOOL svcctl_io_q_query_service_config2(const char *desc, SVCCTL_Q_QUERY_SERVICE_ /******************************************************************* - Creates a service description response buffer. - The format seems to be DWORD:length of buffer - DWORD:offset (fixed as four) - UNISTR: unicode description in the rest of the buffer ********************************************************************/ -void init_service_description_buffer(RPC_DATA_BLOB *str, const char *service_desc, int blob_length) +void init_service_description_buffer(SERVICE_DESCRIPTION *desc, const char *service_desc ) { - uint32 offset; - uint8 *bp; + desc->unknown = 0x04; /* always 0x0000 0004 (no idea what this is) */ + init_unistr( &desc->description, service_desc ); +} - ZERO_STRUCTP(str); +/******************************************************************* +********************************************************************/ - offset = 4; +BOOL svcctl_io_service_description( const char *desc, SERVICE_DESCRIPTION *description, RPC_BUFFER *buffer, int depth ) +{ + prs_struct *ps = &buffer->prs; - /* set up string lengths. */ + prs_debug(ps, depth, desc, "svcctl_io_service_description"); + depth++; - str->buf_len = create_rpc_blob(str, blob_length); - DEBUG(10, ("init_service_description buffer: Allocated a blob of [%d] \n",str->buf_len)); + if ( !prs_uint32("unknown", ps, depth, &description->unknown) ) + return False; + if ( !prs_unistr("description", ps, depth, &description->description) ) + return False; - if ( str && str->buffer && str->buf_len) { - memset(str->buffer,0,str->buf_len); - memcpy(str->buffer, &offset, sizeof(uint32)); - bp = &str->buffer[4]; - if (service_desc) { - rpcstr_push(bp, service_desc,str->buf_len-4,0); + return True; +} + +/******************************************************************* +********************************************************************/ + +uint32 svcctl_sizeof_service_description( SERVICE_DESCRIPTION *desc ) +{ + if ( !desc ) + return 0; + + /* make sure to include the terminating NULL */ + return ( sizeof(uint32) + (2*(str_len_uni(&desc->description)+1)) ); +} + +/******************************************************************* +********************************************************************/ + +static BOOL svcctl_io_action( const char *desc, SC_ACTION *action, prs_struct *ps, int depth ) +{ + + prs_debug(ps, depth, desc, "svcctl_io_action"); + depth++; + + if ( !prs_uint32("type", ps, depth, &action->type) ) + return False; + if ( !prs_uint32("delay", ps, depth, &action->delay) ) + return False; + + return True; +} + +/******************************************************************* +********************************************************************/ + +BOOL svcctl_io_service_fa( const char *desc, SERVICE_FAILURE_ACTIONS *fa, RPC_BUFFER *buffer, int depth ) +{ + prs_struct *ps = &buffer->prs; + int i; + + prs_debug(ps, depth, desc, "svcctl_io_service_description"); + depth++; + + if ( !prs_uint32("reset_period", ps, depth, &fa->reset_period) ) + return False; + + if ( !prs_pointer( desc, ps, depth, (void**)&fa->rebootmsg, sizeof(UNISTR2), (PRS_POINTER_CAST)prs_io_unistr2 ) ) + return False; + if ( !prs_pointer( desc, ps, depth, (void**)&fa->command, sizeof(UNISTR2), (PRS_POINTER_CAST)prs_io_unistr2 ) ) + return False; + + if ( !prs_uint32("num_actions", ps, depth, &fa->num_actions) ) + return False; + + if ( UNMARSHALLING(ps) && fa->num_actions ) { + if ( !(fa->actions = TALLOC_ARRAY( get_talloc_ctx(), SC_ACTION, fa->num_actions )) ) { + DEBUG(0,("svcctl_io_service_fa: talloc() failure!\n")); + return False; } } + + for ( i=0; i<fa->num_actions; i++ ) { + if ( !svcctl_io_action( "actions", &fa->actions[i], ps, depth ) ) + return False; + } + + return True; +} + +/******************************************************************* +********************************************************************/ + +uint32 svcctl_sizeof_service_fa( SERVICE_FAILURE_ACTIONS *fa) +{ + uint32 size = 0; + + if ( !fa ) + return 0; + + size = sizeof(uint32) * 2; + size += sizeof_unistr2( fa->rebootmsg ); + size += sizeof_unistr2( fa->command ); + size += sizeof(SC_ACTION) * fa->num_actions; + + return size; } /******************************************************************* ********************************************************************/ +BOOL svcctl_io_r_query_service_config2(const char *desc, SVCCTL_R_QUERY_SERVICE_CONFIG2 *r_u, prs_struct *ps, int depth) +{ + if ( !r_u ) + return False; + + prs_debug(ps, depth, desc, "svcctl_io_r_query_service_config2"); + depth++; + + if ( !prs_align(ps) ) + return False; + + if (!prs_rpcbuffer("", ps, depth, &r_u->buffer)) + return False; + if(!prs_align(ps)) + return False; + + if (!prs_uint32("needed", ps, depth, &r_u->needed)) + return False; + + if(!prs_werror("status", ps, depth, &r_u->status)) + return False; + + return True; +} + + +/******************************************************************* +********************************************************************/ + BOOL svcctl_io_q_query_service_status_ex(const char *desc, SVCCTL_Q_QUERY_SERVICE_STATUSEX *q_u, prs_struct *ps, int depth) { if (q_u == NULL) @@ -752,7 +908,7 @@ BOOL svcctl_io_q_query_service_status_ex(const char *desc, SVCCTL_Q_QUERY_SERVIC if(!smb_io_pol_hnd("service_pol", &q_u->handle, ps, depth)) return False; - if(!prs_uint32("info_level", ps, depth, &q_u->info_level)) + if(!prs_uint32("level", ps, depth, &q_u->level)) return False; if(!prs_uint32("buffer_size", ps, depth, &q_u->buffer_size)) @@ -771,7 +927,7 @@ BOOL svcctl_io_r_query_service_status_ex(const char *desc, SVCCTL_R_QUERY_SERVIC return False; prs_debug(ps, depth, desc, "svcctl_io_r_query_service_status_ex"); - depth++; + depth++; if (!prs_rpcbuffer("", ps, depth, &r_u->buffer)) return False; @@ -791,37 +947,80 @@ BOOL svcctl_io_r_query_service_status_ex(const char *desc, SVCCTL_R_QUERY_SERVIC /******************************************************************* ********************************************************************/ -BOOL svcctl_io_r_query_service_config2(const char *desc, SVCCTL_R_QUERY_SERVICE_CONFIG2 *r_u, prs_struct *ps, int depth) +BOOL svcctl_io_q_lock_service_db(const char *desc, SVCCTL_Q_LOCK_SERVICE_DB *q_u, prs_struct *ps, int depth) +{ + if (q_u == NULL) + return False; + + prs_debug(ps, depth, desc, "svcctl_io_q_lock_service_db"); + depth++; + + if(!prs_align(ps)) + return False; + + if(!smb_io_pol_hnd("scm_handle", &q_u->handle, ps, depth)) + return False; + + return True; + +} + +/******************************************************************* +********************************************************************/ + +BOOL svcctl_io_r_lock_service_db(const char *desc, SVCCTL_R_LOCK_SERVICE_DB *r_u, prs_struct *ps, int depth) { if ( !r_u ) return False; - prs_debug(ps, depth, desc, "svcctl_io_r_query_service_config2"); + prs_debug(ps, depth, desc, "svcctl_io_r_lock_service_db"); depth++; if(!prs_align(ps)) return False; - if(!prs_uint32("returned", ps, depth, &r_u->returned)) + if(!smb_io_pol_hnd("lock_handle", &r_u->h_lock, ps, depth)) return False; - if (r_u->returned > 4) { - if (!prs_uint32("offset", ps, depth, &r_u->offset)) - return False; + if(!prs_werror("status", ps, depth, &r_u->status)) + return False; - if ( !prs_pointer( desc, ps, depth, (void**)&r_u->description, sizeof(UNISTR2), (PRS_POINTER_CAST)prs_io_unistr2 ) ) - return False; + return True; +} - if(!prs_align(ps)) - return False; - } else { - /* offset does double duty here */ - r_u->offset = 0; - if (!prs_uint32("offset", ps, depth, &r_u->offset)) - return False; - } +/******************************************************************* +********************************************************************/ - if (!prs_uint32("needed", ps, depth, &r_u->needed)) +BOOL svcctl_io_q_unlock_service_db(const char *desc, SVCCTL_Q_UNLOCK_SERVICE_DB *q_u, prs_struct *ps, int depth) +{ + if (q_u == NULL) + return False; + + prs_debug(ps, depth, desc, "svcctl_io_q_unlock_service_db"); + depth++; + + if(!prs_align(ps)) + return False; + + if(!smb_io_pol_hnd("h_lock", &q_u->h_lock, ps, depth)) + return False; + + return True; + +} + +/******************************************************************* +********************************************************************/ + +BOOL svcctl_io_r_unlock_service_db(const char *desc, SVCCTL_R_UNLOCK_SERVICE_DB *r_u, prs_struct *ps, int depth) +{ + if ( !r_u ) + return False; + + prs_debug(ps, depth, desc, "svcctl_io_r_unlock_service_db"); + depth++; + + if(!prs_align(ps)) return False; if(!prs_werror("status", ps, depth, &r_u->status)) @@ -831,3 +1030,5 @@ BOOL svcctl_io_r_query_service_config2(const char *desc, SVCCTL_R_QUERY_SERVICE_ } + + |