s3-svcctl: fix return code for _svcctl_QueryServiceStatusEx.
[metze/samba/wip.git] / source3 / rpc_server / srv_svcctl_nt.c
index 0bed13e522b6cb31b1cad644c1d0bef035651392..2e50d312d61ecb44f71a19516051747428dcc063 100644 (file)
@@ -272,7 +272,8 @@ WERROR _svcctl_OpenSCManagerW(pipes_struct *p,
                return WERR_NOMEM;
 
        se_map_generic( &r->in.access_mask, &scm_generic_map );
-       status = svcctl_access_check( sec_desc, p->pipe_user.nt_user_token, r->in.access_mask, &access_granted );
+       status = svcctl_access_check( sec_desc, p->server_info->ptok,
+                                     r->in.access_mask, &access_granted );
        if ( !NT_STATUS_IS_OK(status) )
                return ntstatus_to_werror( status );
 
@@ -309,7 +310,8 @@ WERROR _svcctl_OpenServiceW(pipes_struct *p,
                return WERR_NOMEM;
 
        se_map_generic( &r->in.access_mask, &svc_generic_map );
-       status = svcctl_access_check( sec_desc, p->pipe_user.nt_user_token, r->in.access_mask, &access_granted );
+       status = svcctl_access_check( sec_desc, p->server_info->ptok,
+                                     r->in.access_mask, &access_granted );
        if ( !NT_STATUS_IS_OK(status) )
                return ntstatus_to_werror( status );
 
@@ -347,7 +349,8 @@ WERROR _svcctl_GetServiceDisplayNameW(pipes_struct *p,
 
        service = r->in.service_name;
 
-       display_name = svcctl_lookup_dispname(p->mem_ctx, service, p->pipe_user.nt_user_token );
+       display_name = svcctl_lookup_dispname(p->mem_ctx, service,
+                                             p->server_info->ptok);
        if (!display_name) {
                display_name = "";
        }
@@ -424,7 +427,7 @@ WERROR _svcctl_enum_services_status(pipes_struct *p, SVCCTL_Q_ENUM_SERVICES_STAT
        size_t buffer_size = 0;
        WERROR result = WERR_OK;
        SERVICE_INFO *info = find_service_info_by_hnd( p, &q_u->handle );
-       NT_USER_TOKEN *token = p->pipe_user.nt_user_token;
+       NT_USER_TOKEN *token = p->server_info->ptok;
 
        /* perform access checks */
 
@@ -552,11 +555,13 @@ WERROR _svcctl_EnumDependentServicesW(pipes_struct *p,
 }
 
 /********************************************************************
+ _svcctl_QueryServiceStatusEx
 ********************************************************************/
 
-WERROR _svcctl_query_service_status_ex( pipes_struct *p, SVCCTL_Q_QUERY_SERVICE_STATUSEX *q_u, SVCCTL_R_QUERY_SERVICE_STATUSEX *r_u )
+WERROR _svcctl_QueryServiceStatusEx(pipes_struct *p,
+                                   struct svcctl_QueryServiceStatusEx *r)
 {
-       SERVICE_INFO *info = find_service_info_by_hnd( p, &q_u->handle );
+       SERVICE_INFO *info = find_service_info_by_hnd( p, r->in.handle );
        uint32 buffer_size;
 
        /* perform access checks */
@@ -570,21 +575,29 @@ WERROR _svcctl_query_service_status_ex( pipes_struct *p, SVCCTL_Q_QUERY_SERVICE_
        /* we have to set the outgoing buffer size to the same as the
           incoming buffer size (even in the case of failure) */
 
-       rpcbuf_init( &r_u->buffer, q_u->buffer_size, p->mem_ctx );
-       r_u->needed = q_u->buffer_size;
+       *r->out.bytes_needed = r->in.buf_size;
 
-       switch ( q_u->level ) {
+       switch ( r->in.info_level ) {
                case SVC_STATUS_PROCESS_INFO:
                {
-                       SERVICE_STATUS_PROCESS svc_stat_proc;
+                       struct SERVICE_STATUS_PROCESS svc_stat_proc;
+                       enum ndr_err_code ndr_err;
+                       DATA_BLOB blob;
 
                        /* Get the status of the service.. */
                        info->ops->service_status( info->name, &svc_stat_proc.status );
                        svc_stat_proc.process_id     = sys_getpid();
                        svc_stat_proc.service_flags  = 0x0;
 
-                       svcctl_io_service_status_process( "", &svc_stat_proc, &r_u->buffer, 0 );
-                       buffer_size = sizeof(SERVICE_STATUS_PROCESS);
+                       ndr_err = ndr_push_struct_blob(&blob, p->mem_ctx, NULL,
+                                                      &svc_stat_proc,
+                                                      (ndr_push_flags_fn_t)ndr_push_SERVICE_STATUS_PROCESS);
+                       if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+                               return WERR_INVALID_PARAM;
+                       }
+
+                       r->out.buffer = blob.data;
+                       buffer_size = sizeof(struct SERVICE_STATUS_PROCESS);
                        break;
                }
 
@@ -594,10 +607,11 @@ WERROR _svcctl_query_service_status_ex( pipes_struct *p, SVCCTL_Q_QUERY_SERVICE_
 
 
         buffer_size += buffer_size % 4;
-       r_u->needed = (buffer_size > q_u->buffer_size) ? buffer_size : q_u->buffer_size;
+       *r->out.bytes_needed = (buffer_size > r->in.buf_size) ? buffer_size : r->in.buf_size;
 
-        if (buffer_size > q_u->buffer_size )
-                return WERR_MORE_DATA;
+        if (buffer_size > r->in.buf_size ) {
+                return WERR_INSUFFICIENT_BUFFER;
+       }
 
        return WERR_OK;
 }
@@ -680,11 +694,12 @@ WERROR _svcctl_QueryServiceConfigW(pipes_struct *p,
 
        *r->out.bytes_needed = r->in.buf_size;
 
-       wresult = fill_svc_config( p->mem_ctx, info->name, r->out.query, p->pipe_user.nt_user_token );
+       wresult = fill_svc_config( p->mem_ctx, info->name, r->out.query,
+                                  p->server_info->ptok);
        if ( !W_ERROR_IS_OK(wresult) )
                return wresult;
 
-       buffer_size = ndr_size_QUERY_SERVICE_CONFIG(r->out.query, 0);
+       buffer_size = ndr_size_QUERY_SERVICE_CONFIG(r->out.query, NULL, 0);
        *r->out.bytes_needed = (buffer_size > r->in.buf_size) ? buffer_size : r->in.buf_size;
 
         if (buffer_size > r->in.buf_size ) {
@@ -723,7 +738,8 @@ WERROR _svcctl_query_service_config2( pipes_struct *p, SVCCTL_Q_QUERY_SERVICE_CO
                        SERVICE_DESCRIPTION desc_buf;
                        const char *description;
 
-                       description = svcctl_lookup_description(p->mem_ctx, info->name, p->pipe_user.nt_user_token );
+                       description = svcctl_lookup_description(
+                               p->mem_ctx, info->name, p->server_info->ptok);
 
                        ZERO_STRUCTP( &desc_buf );
 
@@ -833,7 +849,7 @@ WERROR _svcctl_QueryServiceObjectSecurity(pipes_struct *p,
        if ( !(sec_desc = svcctl_get_secdesc( p->mem_ctx, info->name, get_root_nt_token() )) )
                 return WERR_NOMEM;
 
-       *r->out.needed = ndr_size_security_descriptor( sec_desc, 0 );
+       *r->out.needed = ndr_size_security_descriptor( sec_desc, NULL, 0 );
 
        if ( *r->out.needed > r->in.buffer_size ) {
                ZERO_STRUCTP( &r->out.buffer );
@@ -903,7 +919,8 @@ WERROR _svcctl_SetServiceObjectSecurity(pipes_struct *p,
 
        /* store the new SD */
 
-       if ( !svcctl_set_secdesc( p->mem_ctx, info->name, sec_desc, p->pipe_user.nt_user_token ) )
+       if ( !svcctl_set_secdesc( p->mem_ctx, info->name, sec_desc,
+                                 p->server_info->ptok) )
                return WERR_ACCESS_DENIED;
 
        return WERR_OK;
@@ -1072,12 +1089,6 @@ WERROR _svcctl_QueryServiceConfig2W(pipes_struct *p, struct svcctl_QueryServiceC
        return WERR_NOT_SUPPORTED;
 }
 
-WERROR _svcctl_QueryServiceStatusEx(pipes_struct *p, struct svcctl_QueryServiceStatusEx *r)
-{
-       p->rng_fault_state = True;
-       return WERR_NOT_SUPPORTED;
-}
-
 WERROR _EnumServicesStatusExA(pipes_struct *p, struct EnumServicesStatusExA *r)
 {
        p->rng_fault_state = True;