summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLuke Leighton <lkcl@samba.org>2000-03-17 18:03:47 +0000
committerLuke Leighton <lkcl@samba.org>2000-03-17 18:03:47 +0000
commitca079cdbdc0a8bf681ded1651cb320a7e3e6bbfb (patch)
treee4ce6c84d6ffca219c9fb3e6edf2a0200678a923
parentf8777b82d8b310ca0273fd91b9941e072c8b4619 (diff)
downloadsamba-ca079cdbdc0a8bf681ded1651cb320a7e3e6bbfb.tar.gz
samba-ca079cdbdc0a8bf681ded1651cb320a7e3e6bbfb.tar.xz
samba-ca079cdbdc0a8bf681ded1651cb320a7e3e6bbfb.zip
From Elrond@Wunder-Nett.org Sat Mar 18 04:49:11 2000
Date: Fri, 17 Mar 2000 16:02:28 +0100 From: Elrond <Elrond@Wunder-Nett.org> To: Luke Kenneth Casson Leighton <lkcl@samba.org> Subject: Re: SVC_UNKNOWN_3 On Fri, Mar 17, 2000 at 08:27:49AM +1100, Luke Kenneth Casson Leighton wrote: > it's probably a delete service :-) :-) > > check your box!!! [...] Hi Luke, You pass in a Service-Control-Manager-Handle, not a service-handle, so it can't be service-delete. It could of course be scman-del... which would be quite crazy. (includind the fact, that this is done by srvmgr, which hasn't any means to add/del a service...) But it was all my fault. I copied cli_svc.c:svc_close() over to svc_unknown_3... and guess what... I changed everything except the Opcode... After that I was more successful: You pass in a scman_hnd, and get back some other handle...I don't know yet, what it is good for... I added an appropiate server-side implementation and srvmgr.exe got a bit further, but now it calls opcode 11 on a service-handle. Maybe more soon. (I'm pressing the "Startup"-button in Services in srvmgr) The patch contains: - complete server and client-side implementation of SVC_UNKNOWN_3 (yet no idea, what it is, but we have it) - --with-privatedir=... from HEAD is now completely in TNG - merged some things from HEAD into lib/time.c PLEASE DON'T run indent on lib/time.c ! [lkcl: okie] - dito for param/loadparm.c PLEASE DON'T run indent on param/loadparm.c ! [lkcl: okie] Elrond
-rw-r--r--source/Makefile.in8
-rw-r--r--source/include/proto.h156
-rw-r--r--source/include/rpc_client_proto.h2
-rw-r--r--source/include/rpc_parse_proto.h2
-rw-r--r--source/include/rpc_svcctl.h9
-rw-r--r--source/include/winbindd_proto.h3
-rw-r--r--source/lib/time.c11
-rw-r--r--source/param/loadparm.c17
-rw-r--r--source/rpc_client/cli_svcctl.c36
-rw-r--r--source/rpc_parse/parse_svc.c19
-rw-r--r--source/rpc_server/srv_svcctl.c24
-rw-r--r--source/rpcclient/cmd_svcctl.c8
-rw-r--r--source/svcctld/srv_svcctl_nt.c21
13 files changed, 238 insertions, 78 deletions
diff --git a/source/Makefile.in b/source/Makefile.in
index 1dc2f1019a3..1c0ea4fed73 100644
--- a/source/Makefile.in
+++ b/source/Makefile.in
@@ -55,11 +55,11 @@ NTDRIVERSDIR = $(LIBDIR)
PASSWD_PROGRAM = /bin/passwd
PRIVATEDIR = @privatedir@
-SMB_PASSWD_FILE = $(BASEDIR)/private/smbpasswd
+SMB_PASSWD_FILE = $(PRIVATEDIR)/smbpasswd
+SMB_PASSGRP_FILE = $(PRIVATEDIR)/smbpassgrp
+SMB_GROUP_FILE = $(PRIVATEDIR)/smbgroup
+SMB_ALIAS_FILE = $(PRIVATEDIR)/smbalias
SAM_DIR = $(BASEDIR)/sam
-SMB_PASSGRP_FILE = $(BASEDIR)/private/smbpassgrp
-SMB_GROUP_FILE = $(BASEDIR)/private/smbgroup
-SMB_ALIAS_FILE = $(BASEDIR)/private/smbalias
SMB_PASSWD_PROGRAM = $(BINDIR)/smbpasswd
# This is where SWAT images and help files go
diff --git a/source/include/proto.h b/source/include/proto.h
index 439ab4438cc..43d282a6974 100644
--- a/source/include/proto.h
+++ b/source/include/proto.h
@@ -1426,72 +1426,98 @@ BOOL node_status(struct subnet_record *subrec, struct nmb_name *nmbname,
uint16 get_nb_flags(char *buf);
void set_nb_flags(char *buf, uint16 nb_flags);
-struct response_record *queue_register_name( struct subnet_record *subrec,
- response_function resp_fn,
- timeout_response_function timeout_fn,
- register_name_success_function success_fn,
- register_name_fail_function fail_fn,
- struct userdata_struct *userdata,
- struct nmb_name *nmbname,
- uint16 nb_flags);
-struct response_record *queue_register_multihomed_name( struct subnet_record *subrec,
- response_function resp_fn,
- timeout_response_function timeout_fn,
- register_name_success_function success_fn,
- register_name_fail_function fail_fn,
- struct userdata_struct *userdata,
- struct nmb_name *nmbname,
- uint16 nb_flags,
- struct in_addr register_ip);
-struct response_record *queue_release_name( struct subnet_record *subrec,
- response_function resp_fn,
- timeout_response_function timeout_fn,
- release_name_success_function success_fn,
- release_name_fail_function fail_fn,
- struct userdata_struct *userdata,
- struct nmb_name *nmbname,
- uint16 nb_flags,
- struct in_addr release_ip);
-struct response_record *queue_refresh_name( struct subnet_record *subrec,
- response_function resp_fn,
- timeout_response_function timeout_fn,
- refresh_name_success_function success_fn,
- refresh_name_fail_function fail_fn,
- struct userdata_struct *userdata,
- struct name_record *namerec,
- struct in_addr refresh_ip);
-struct response_record *queue_query_name( struct subnet_record *subrec,
- response_function resp_fn,
- timeout_response_function timeout_fn,
- query_name_success_function success_fn,
- query_name_fail_function fail_fn,
- struct userdata_struct *userdata,
- struct nmb_name *nmbname);
-struct response_record *queue_query_name_from_wins_server( struct in_addr to_ip,
- response_function resp_fn,
- timeout_response_function timeout_fn,
- query_name_success_function success_fn,
- query_name_fail_function fail_fn,
- struct userdata_struct *userdata,
- struct nmb_name *nmbname);
-struct response_record *queue_node_status( struct subnet_record *subrec,
- response_function resp_fn,
- timeout_response_function timeout_fn,
- node_status_success_function success_fn,
- node_status_fail_function fail_fn,
- struct userdata_struct *userdata,
- struct nmb_name *nmbname,
- struct in_addr send_ip);
+struct response_record *queue_register_name(struct subnet_record *subrec,
+ response_function resp_fn,
+ timeout_response_function
+ timeout_fn,
+ register_name_success_function
+ success_fn,
+ register_name_fail_function
+ fail_fn,
+ struct userdata_struct *userdata,
+ struct nmb_name *nmbname,
+ uint16 nb_flags);
+struct response_record *queue_register_multihomed_name(struct subnet_record
+ *subrec,
+ response_function
+ resp_fn,
+ timeout_response_function
+ timeout_fn,
+ register_name_success_function
+ success_fn,
+ register_name_fail_function
+ fail_fn,
+ struct userdata_struct
+ *userdata,
+ struct nmb_name
+ *nmbname,
+ uint16 nb_flags,
+ struct in_addr
+ register_ip);
+struct response_record *queue_release_name(struct subnet_record *subrec,
+ response_function resp_fn,
+ timeout_response_function
+ timeout_fn,
+ release_name_success_function
+ success_fn,
+ release_name_fail_function fail_fn,
+ struct userdata_struct *userdata,
+ struct nmb_name *nmbname,
+ uint16 nb_flags,
+ struct in_addr release_ip);
+struct response_record *queue_refresh_name(struct subnet_record *subrec,
+ response_function resp_fn,
+ timeout_response_function
+ timeout_fn,
+ refresh_name_success_function
+ success_fn,
+ refresh_name_fail_function fail_fn,
+ struct userdata_struct *userdata,
+ struct name_record *namerec,
+ struct in_addr refresh_ip);
+struct response_record *queue_query_name(struct subnet_record *subrec,
+ response_function resp_fn,
+ timeout_response_function timeout_fn,
+ query_name_success_function
+ success_fn,
+ query_name_fail_function fail_fn,
+ struct userdata_struct *userdata,
+ struct nmb_name *nmbname);
+struct response_record *queue_query_name_from_wins_server(struct in_addr
+ to_ip,
+ response_function
+ resp_fn,
+ timeout_response_function
+ timeout_fn,
+ query_name_success_function
+ success_fn,
+ query_name_fail_function
+ fail_fn,
+ struct
+ userdata_struct
+ *userdata,
+ struct nmb_name
+ *nmbname);
+struct response_record *queue_node_status(struct subnet_record *subrec,
+ response_function resp_fn,
+ timeout_response_function
+ timeout_fn,
+ node_status_success_function
+ success_fn,
+ node_status_fail_function fail_fn,
+ struct userdata_struct *userdata,
+ struct nmb_name *nmbname,
+ struct in_addr send_ip);
void reply_netbios_packet(struct packet_struct *orig_packet,
- int rcode, enum netbios_reply_type_code rcv_code, int opcode,
- int ttl, char *data,int len);
+ int rcode, enum netbios_reply_type_code rcv_code,
+ int opcode, int ttl, char *data, int len);
void run_packet_queue(void);
void retransmit_or_expire_response_records(time_t t);
BOOL listen_for_packets(BOOL run_election);
-BOOL send_mailslot(BOOL unique, char *mailslot,char *buf,int len,
- char *srcname, int src_type,
- char *dstname, int dest_type,
- struct in_addr dest_ip,struct in_addr src_ip,
+BOOL send_mailslot(BOOL unique, char *mailslot, char *buf, int len,
+ char *srcname, int src_type,
+ char *dstname, int dest_type,
+ struct in_addr dest_ip, struct in_addr src_ip,
int dest_port);
/*The following definitions come from nmbd/nmbd_processlogon.c */
@@ -1677,6 +1703,9 @@ BOOL lp_client_schannel(void);
BOOL lp_server_schannel(void);
BOOL lp_syslog_only(void);
BOOL lp_timestamp_logs(void);
+BOOL lp_debug_hires_timestamp(void);
+BOOL lp_debug_pid(void);
+BOOL lp_debug_uid(void);
BOOL lp_browse_list(void);
BOOL lp_unix_realname(void);
BOOL lp_nis_home_map(void);
@@ -2529,7 +2558,7 @@ BOOL svc_change_svc_cfg( POLICY_HND *hnd,
char* dependencies, char* service_start_name,
char* password,
char* disp_name);
-BOOL svc_unknown_3(const POLICY_HND *scman_hnd);
+BOOL svc_unknown_3(const POLICY_HND *scman_hnd, POLICY_HND *hnd);
/*The following definitions come from rpc_client/cli_use.c */
@@ -4845,6 +4874,7 @@ uint32 _svc_query_disp_name(const POLICY_HND *scman_pol,
uint32 buf_size,
UNISTR2 *uni_disp_name,
uint32 *pbuf_size);
+uint32 _svc_unknown_3(const POLICY_HND *scman_hnd, POLICY_HND *hnd);
/*The following definitions come from svcctld/svcctld.c */
diff --git a/source/include/rpc_client_proto.h b/source/include/rpc_client_proto.h
index a6bedec8d0a..28f96834f90 100644
--- a/source/include/rpc_client_proto.h
+++ b/source/include/rpc_client_proto.h
@@ -446,7 +446,7 @@ BOOL svc_change_svc_cfg( POLICY_HND *hnd,
char* dependencies, char* service_start_name,
char* password,
char* disp_name);
-BOOL svc_unknown_3(const POLICY_HND *scman_hnd);
+BOOL svc_unknown_3(const POLICY_HND *scman_hnd, POLICY_HND *hnd);
/*The following definitions come from rpc_client/cli_use.c */
diff --git a/source/include/rpc_parse_proto.h b/source/include/rpc_parse_proto.h
index 5de27e3a1dd..5a81fa930d5 100644
--- a/source/include/rpc_parse_proto.h
+++ b/source/include/rpc_parse_proto.h
@@ -1233,6 +1233,8 @@ BOOL make_svc_r_change_svc_config(SVC_R_CHANGE_SVC_CONFIG *r_c,
BOOL svc_io_r_change_svc_config(char *desc, SVC_R_CHANGE_SVC_CONFIG *r_u, prs_struct *ps, int depth);
BOOL svc_io_q_unknown_3(char *desc, SVC_Q_UNKNOWN_3 *q_u,
prs_struct *ps, int depth);
+BOOL svc_io_r_unknown_3(char *desc, SVC_R_UNKNOWN_3 *r_u,
+ prs_struct *ps, int depth);
/*The following definitions come from rpc_parse/parse_wks.c */
diff --git a/source/include/rpc_svcctl.h b/source/include/rpc_svcctl.h
index 4185047a93f..c5c30617d29 100644
--- a/source/include/rpc_svcctl.h
+++ b/source/include/rpc_svcctl.h
@@ -286,11 +286,18 @@ typedef struct r_svc_change_svc_cfg_info
/* SVC_Q_UNKNOWN_3 */
-typedef struct _svc_unknown_3
+typedef struct _svc_q_unknown_3
{
POLICY_HND scman_hnd;
} SVC_Q_UNKNOWN_3;
+/* SVC_R_UNKNOWN_3 */
+typedef struct _svc_r_unknown_3
+{
+ POLICY_HND hnd;
+ uint32 status; /* 0x5 seems to mean access denied... */
+} SVC_R_UNKNOWN_3;
+
#endif /* _RPC_SVCCTL_H */
diff --git a/source/include/winbindd_proto.h b/source/include/winbindd_proto.h
index 0e46aa0659e..b2707570560 100644
--- a/source/include/winbindd_proto.h
+++ b/source/include/winbindd_proto.h
@@ -1015,6 +1015,9 @@ BOOL lp_client_schannel(void);
BOOL lp_server_schannel(void);
BOOL lp_syslog_only(void);
BOOL lp_timestamp_logs(void);
+BOOL lp_debug_hires_timestamp(void);
+BOOL lp_debug_pid(void);
+BOOL lp_debug_uid(void);
BOOL lp_browse_list(void);
BOOL lp_unix_realname(void);
BOOL lp_nis_home_map(void);
diff --git a/source/lib/time.c b/source/lib/time.c
index c332b906a0c..0847f18a1d3 100644
--- a/source/lib/time.c
+++ b/source/lib/time.c
@@ -298,6 +298,13 @@ void unix_to_nt_time(NTTIME *nt, time_t t)
{
double d;
+ if (t==0)
+ {
+ nt->low = 0;
+ nt->high = 0;
+ return;
+ }
+
/* this converts GMT to kludge-GMT */
t -= LocTimeDiff(t) - serverzone;
@@ -497,6 +504,8 @@ char *http_timestring(time_t t)
else
#ifndef HAVE_STRFTIME
fstrcpy(buf, asctime(tm));
+ if(buf[strlen(buf)-1] == '\n')
+ buf[strlen(buf)-1] = 0;
#else /* !HAVE_STRFTIME */
strftime(buf, sizeof(buf)-1, "%a, %d %b %Y %H:%M:%S %Z", tm);
#endif /* !HAVE_STRFTIME */
@@ -506,7 +515,7 @@ char *http_timestring(time_t t)
/****************************************************************************
- return the date and time as a string
+ Return the date and time as a string
****************************************************************************/
char *timestring(void )
{
diff --git a/source/param/loadparm.c b/source/param/loadparm.c
index 5f6b0b5bdb1..ae1d531ddf1 100644
--- a/source/param/loadparm.c
+++ b/source/param/loadparm.c
@@ -257,6 +257,9 @@ typedef struct
char *sMysqlHost;
char *sMysqlPassFile;
#endif
+ BOOL bDebugHiresTimestamp;
+ BOOL bDebugPid;
+ BOOL bDebugUid;
} global;
static global Globals;
@@ -640,6 +643,9 @@ static struct parm_struct parm_table[] =
{"max log size", P_INTEGER, P_GLOBAL, &Globals.max_log_size, NULL, NULL, 0},
{"timestamp logs", P_BOOL, P_GLOBAL, &Globals.bTimestampLogs, NULL, NULL, 0},
{"debug timestamp", P_BOOL, P_GLOBAL, &Globals.bTimestampLogs, NULL, NULL, 0},
+ {"debug hires timestamp", P_BOOL, P_GLOBAL, &Globals.bDebugHiresTimestamp, NULL, NULL, 0},
+ {"debug pid", P_BOOL, P_GLOBAL, &Globals.bDebugPid, NULL, NULL, 0},
+ {"debug uid", P_BOOL, P_GLOBAL, &Globals.bDebugUid, NULL, NULL, 0},
{"status", P_BOOL, P_LOCAL, &sDefault.status, NULL, NULL, FLAG_GLOBAL},
{"Protocol Options", P_SEP, P_SEPARATOR},
@@ -953,6 +959,9 @@ static void init_globals(void)
Globals.syslog = 1;
Globals.bSyslogOnly = False;
Globals.bTimestampLogs = False;
+ Globals.bDebugHiresTimestamp = False;
+ Globals.bDebugPid = False;
+ Globals.bDebugUid = False;
Globals.os_level = 32;
Globals.max_ttl = 60*60*24*3; /* 3 days default. */
Globals.max_wins_ttl = 60*60*24*6; /* 6 days default. */
@@ -1101,7 +1110,7 @@ static void init_locals(void)
string_initial(&sDefault.szLprmcommand,"lprm -P%p %j");
string_initial(&sDefault.szPrintcommand,"lpr -r -P%p %s");
break;
-
+
case PRINT_LPRNG:
string_initial(&sDefault.szLpqcommand,"lpq -P%p");
string_initial(&sDefault.szLprmcommand,"lprm -P%p %j");
@@ -1174,7 +1183,8 @@ static char *lp_user_string(const user_struct *vuser, char *s)
if (buflen[next] != len) {
buflen[next] = len;
- if (bufs[next]) free(bufs[next]);
+ if (bufs[next])
+ free(bufs[next]);
bufs[next] = (char *)malloc(len);
if (!bufs[next]) {
DEBUG(0,("out of memory in lp_string()"));
@@ -1377,6 +1387,9 @@ FN_GLOBAL_BOOL(lp_client_schannel,&Globals.bClientSChannel)
FN_GLOBAL_BOOL(lp_server_schannel,&Globals.bServerSChannel)
FN_GLOBAL_BOOL(lp_syslog_only,&Globals.bSyslogOnly)
FN_GLOBAL_BOOL(lp_timestamp_logs,&Globals.bTimestampLogs)
+FN_GLOBAL_BOOL(lp_debug_hires_timestamp,&Globals.bDebugHiresTimestamp)
+FN_GLOBAL_BOOL(lp_debug_pid,&Globals.bDebugPid)
+FN_GLOBAL_BOOL(lp_debug_uid,&Globals.bDebugUid)
FN_GLOBAL_BOOL(lp_browse_list,&Globals.bBrowseList)
FN_GLOBAL_BOOL(lp_unix_realname,&Globals.bUnixRealname)
FN_GLOBAL_BOOL(lp_nis_home_map,&Globals.bNISHomeMap)
diff --git a/source/rpc_client/cli_svcctl.c b/source/rpc_client/cli_svcctl.c
index 0665825ddd4..9aa587e881b 100644
--- a/source/rpc_client/cli_svcctl.c
+++ b/source/rpc_client/cli_svcctl.c
@@ -580,7 +580,7 @@ BOOL svc_change_svc_cfg( POLICY_HND *hnd,
/****************************************************************************
do a SVC unknown 3
****************************************************************************/
-BOOL svc_unknown_3(const POLICY_HND *scman_hnd)
+BOOL svc_unknown_3(const POLICY_HND *scman_hnd, POLICY_HND *hnd)
{
prs_struct rbuf;
prs_struct buf;
@@ -606,9 +606,39 @@ BOOL svc_unknown_3(const POLICY_HND *scman_hnd)
/* turn parameters into data stream */
if (svc_io_q_unknown_3("", &q_c, &buf, 0) &&
- rpc_con_pipe_req(con, SVC_CLOSE, &buf, &rbuf))
+ rpc_con_pipe_req(con, SVC_UNKNOWN_3, &buf, &rbuf))
{
- ;
+ SVC_R_UNKNOWN_3 r_o;
+ BOOL p;
+
+ ZERO_STRUCT(r_o);
+
+ p = svc_io_r_unknown_3("", &r_o, &rbuf, 0);
+
+ if (p) p = (rbuf.offset != 0);
+
+ if (p && r_o.status != 0)
+ {
+ /* report error code */
+ DEBUG(1,("SVC_OPEN_SC_MAN: %s\n", get_nt_error_msg(r_o.status)));
+ p = False;
+ }
+
+ if (p)
+ {
+ /* ok, at last: we're happy. return the policy handle */
+ *hnd = r_o.hnd;
+ valid_req = register_policy_hnd(get_global_hnd_cache(),
+ cli_con_sec_ctx(con),
+ hnd, 0x0) &&
+ set_policy_con(get_global_hnd_cache(), hnd, con,
+ cli_connection_unlink);
+ if (valid_req)
+ {
+ policy_hnd_set_name(get_global_hnd_cache(),
+ hnd, "unknown 3 handle");
+ }
+ }
}
prs_free_data(&rbuf);
diff --git a/source/rpc_parse/parse_svc.c b/source/rpc_parse/parse_svc.c
index f7ebcc259e2..b924b0bcaaf 100644
--- a/source/rpc_parse/parse_svc.c
+++ b/source/rpc_parse/parse_svc.c
@@ -901,3 +901,22 @@ BOOL svc_io_q_unknown_3(char *desc, SVC_Q_UNKNOWN_3 *q_u,
return smb_io_pol_hnd("scman_hnd", &(q_u->scman_hnd), ps, depth);
}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL svc_io_r_unknown_3(char *desc, SVC_R_UNKNOWN_3 *r_u,
+ prs_struct *ps, int depth)
+{
+ if (r_u == NULL) return False;
+
+ prs_debug(ps, depth, desc, "svc_io_r_unknown_3");
+ depth++;
+
+ prs_align(ps);
+
+ smb_io_pol_hnd("", &(r_u->hnd), ps, depth);
+ prs_uint32("status", ps, depth, &(r_u->status));
+
+ return True;
+}
diff --git a/source/rpc_server/srv_svcctl.c b/source/rpc_server/srv_svcctl.c
index 17cf5ff86ee..6962ef778c8 100644
--- a/source/rpc_server/srv_svcctl.c
+++ b/source/rpc_server/srv_svcctl.c
@@ -228,6 +228,29 @@ static BOOL api_svc_query_disp_name( rpcsrv_struct *p, prs_struct *data,
}
/*******************************************************************
+ api_svc_unknown_3
+ ********************************************************************/
+static BOOL api_svc_unknown_3(rpcsrv_struct *p, prs_struct *data,
+ prs_struct *rdata)
+{
+ SVC_Q_UNKNOWN_3 q_u;
+ SVC_R_UNKNOWN_3 r_u;
+
+ ZERO_STRUCT(q_u);
+ ZERO_STRUCT(r_u);
+
+ if (!svc_io_q_unknown_3("", &q_u, data, 0))
+ {
+ return False;
+ }
+
+ r_u.status = _svc_unknown_3(&q_u.scman_hnd, &r_u.hnd);
+
+ /* store the response in the SMB stream */
+ return svc_io_r_unknown_3("", &r_u, rdata, 0);
+}
+
+/*******************************************************************
array of \PIPE\svcctl operations
********************************************************************/
static const struct api_struct api_svc_cmds[] =
@@ -239,6 +262,7 @@ static const struct api_struct api_svc_cmds[] =
{ "SVC_QUERY_DISP_NAME" , SVC_QUERY_DISP_NAME , api_svc_query_disp_name },
{ "SVC_START_SERVICE" , SVC_START_SERVICE , api_svc_start_service },
{ "SVC_STOP_SERVICE" , SVC_STOP_SERVICE , api_svc_stop_service },
+ { "SVC_UNKNOWN_3" , SVC_UNKNOWN_3 , api_svc_unknown_3 },
{ NULL , 0 , NULL }
};
diff --git a/source/rpcclient/cmd_svcctl.c b/source/rpcclient/cmd_svcctl.c
index 764f908b0d1..78df344a1ef 100644
--- a/source/rpcclient/cmd_svcctl.c
+++ b/source/rpcclient/cmd_svcctl.c
@@ -413,6 +413,7 @@ void cmd_svc_unk3(struct client_info *info, int argc, char *argv[])
BOOL res = True;
BOOL res1 = True;
POLICY_HND pol_scm;
+ POLICY_HND unkhnd;
fstring srv_name;
@@ -423,12 +424,13 @@ void cmd_svc_unk3(struct client_info *info, int argc, char *argv[])
DEBUG(4,("cmd_svc_unk3: server:%s\n", srv_name));
/* open service control manager receive a policy handle */
- res = res ? svc_open_sc_man(srv_name, NULL, 0x80000000,
+ res = res ? svc_open_sc_man(srv_name, NULL, 0x000f0009,
&pol_scm) : False;
- res1 = res ? svc_unknown_3(&pol_scm) : False;
+ res1 = res ? svc_unknown_3(&pol_scm, &unkhnd) : False;
+ if (res1) svc_close(&unkhnd);
- res = res ? svc_close(&pol_scm) : False;
+ res = res ? svc_close(&pol_scm) : False;
if (res1)
{
diff --git a/source/svcctld/srv_svcctl_nt.c b/source/svcctld/srv_svcctl_nt.c
index 4dae346929a..aecc1dfeff9 100644
--- a/source/svcctld/srv_svcctl_nt.c
+++ b/source/svcctld/srv_svcctl_nt.c
@@ -337,3 +337,24 @@ uint32 _svc_query_disp_name(const POLICY_HND *scman_pol,
return NT_STATUS_NOPROBLEMO;
}
+
+/*******************************************************************
+ _svc_open_service
+ ********************************************************************/
+uint32 _svc_unknown_3(const POLICY_HND *scman_hnd, POLICY_HND *hnd)
+{
+ if (find_policy_by_hnd(get_global_hnd_cache(), scman_hnd) == -1)
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ if (!open_policy_hnd_link(get_global_hnd_cache(),
+ scman_hnd, hnd, 0x0))
+ {
+ return NT_STATUS_TOO_MANY_SECRETS; /* ha ha very droll */
+ }
+
+ policy_hnd_set_name(get_global_hnd_cache(), hnd, "unknown 3 handle");
+
+ return NT_STATUS_NOPROBLEMO;
+}