summaryrefslogtreecommitdiff
path: root/source3
diff options
context:
space:
mode:
authorMatthew Chapman <matty@samba.org>1999-03-18 05:16:59 +0000
committerMatthew Chapman <matty@samba.org>1999-03-18 05:16:59 +0000
commite8ac69c16877dd827719134dbce49f4aa3608c9d (patch)
tree8b2bc2837d284f32b9f871563f7c0e1b5caf6c06 /source3
parent5a6db490ea56d6492f268b8c5fbc2bc017ba87b6 (diff)
downloadsamba-e8ac69c16877dd827719134dbce49f4aa3608c9d.tar.gz
samba-e8ac69c16877dd827719134dbce49f4aa3608c9d.tar.bz2
samba-e8ac69c16877dd827719134dbce49f4aa3608c9d.zip
Adding LSA_OPENSECRET (-> LsarOpenSecret) and LSA_QUERYSECRET
(-> LsarQuerySecret) on client side, including rpcclient command "querysecret" for others to play with. The major obstacle is working out the encryption algorithm used for the secret value. It definitely uses the NT hash as part of the key, and it seems the block size is 64 bits - probably DES based - but I can't work out what's done in between. Help required. (This used to be commit 365fa3b5fbf551670acc91f593138a7e91a5f7fa)
Diffstat (limited to 'source3')
-rw-r--r--source3/include/proto.h53
-rw-r--r--source3/include/rpc_lsa.h60
-rw-r--r--source3/include/rpc_misc.h9
-rw-r--r--source3/rpc_client/cli_lsarpc.c115
-rw-r--r--source3/rpc_parse/parse_lsa.c165
-rw-r--r--source3/rpc_parse/parse_misc.c31
-rw-r--r--source3/rpcclient/cmd_lsarpc.c69
-rw-r--r--source3/rpcclient/rpcclient.c1
8 files changed, 467 insertions, 36 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h
index af8eaa4074..46dc35b2aa 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -1402,41 +1402,6 @@ struct smb_passwd *ldap_getpw(void);
BOOL ldap_allocaterid(uint32 *rid);
struct smb_passdb_ops *ldap_initialise_password_db(void);
-/*The following definitions come from passdb/mysqlpass.c */
-
-int mysql_db_lock_connect( MYSQL *handle );
-void *mysql_startpwent( BOOL update );
-void mysql_endpwent( void *ptr );
-SMB_BIG_UINT mysql_getpwpos(void *vp);
-BOOL mysql_setpwpos(void *vp, SMB_BIG_UINT pos);
-void *mysql_fill_smb_passwd( MYSQL_ROW *row );
-struct smb_passwd *mysql_getsmbpwent(void *vp);
-void *mysql_fetch_passwd( void *(*filler)(MYSQL_ROW*), char *where );
-void *mysql_getpwuid(void *(*filler)(MYSQL_ROW *), uid_t uid);
-struct smb_passwd *mysql_getsmbpwuid(uid_t uid);
-void *mysql_getpwnam(void *(*filler)(MYSQL_ROW *), char *field, const char *name);
-struct smb_passwd *mysql_getsmbpwnam(const char *unix_name);
-BOOL mysql_del_smb( MYSQL *handle, char *unix_name );
-BOOL mysql_add_smb( MYSQL *handle, struct smb_passwd *smb );
-BOOL mysql_mod_smb( MYSQL *handle, struct smb_passwd *smb, BOOL override );
-BOOL mysql_add_smbpwd_entry(struct smb_passwd *smb);
-BOOL mysql_mod_smbpwd_entry(struct smb_passwd *smb, BOOL override);
-struct smb_passdb_ops *mysql_initialise_password_db(void);
-
-/*The following definitions come from passdb/mysqlsampass.c */
-
-void *mysql_fill_sam_passwd( MYSQL_ROW *row );
-struct sam_passwd *mysql_getsampwent(void *vp);
-struct sam_passwd *mysql_getsampwrid(uint32 rid);
-struct sam_passwd *mysql_getsampwuid(uid_t uid);
-struct sam_passwd *mysql_getsampwntnam(const char *nt_name);
-struct sam_disp_info *mysql_getsamdispntnam(const char *nt_name);
-struct sam_disp_info *mysql_getsamdisprid(uint32 rid);
-struct sam_disp_info *mysql_getsamdispent(void *vp);
-BOOL mysql_add_sampwd_entry(struct sam_passwd *sam);
-BOOL mysql_mod_sampwd_entry(struct sam_passwd *sam, BOOL override);
-struct sam_passdb_ops *mysql_initialise_sam_password_db(void);
-
/*The following definitions come from passdb/nispass.c */
struct passdb_ops *nisplus_initialise_password_db(void);
@@ -1599,6 +1564,12 @@ BOOL cli_nt_logoff(struct cli_state *cli, uint16 fnum, NET_ID_INFO_CTR *ctr);
BOOL lsa_open_policy(struct cli_state *cli, uint16 fnum,
char *server_name, POLICY_HND *hnd,
BOOL sec_qos);
+BOOL lsa_open_secret(struct cli_state *cli, uint16 fnum,
+ POLICY_HND *hnd_pol, char *secret_name, uint32 des_access,
+ POLICY_HND *hnd_secret);
+BOOL lsa_query_secret(struct cli_state *cli, uint16 fnum,
+ POLICY_HND *pol, unsigned char secret[24],
+ NTTIME *lastupdate);
BOOL lsa_lookup_names(struct cli_state *cli, uint16 fnum,
POLICY_HND *hnd,
int num_names,
@@ -1885,6 +1856,15 @@ void lsa_io_q_open_pol2(char *desc, LSA_Q_OPEN_POL2 *r_q, prs_struct *ps, int d
void lsa_io_r_open_pol2(char *desc, LSA_R_OPEN_POL2 *r_p, prs_struct *ps, int depth);
void make_q_query(LSA_Q_QUERY_INFO *q_q, POLICY_HND *hnd, uint16 info_class);
void lsa_io_q_query(char *desc, LSA_Q_QUERY_INFO *q_q, prs_struct *ps, int depth);
+void make_q_open_secret(LSA_Q_OPEN_SECRET *q_o, POLICY_HND *pol_hnd,
+ char *secret_name, uint32 desired_access);
+void lsa_io_q_open_secret(char *desc, LSA_Q_OPEN_SECRET *q_o, prs_struct *ps, int depth);
+void lsa_io_r_open_secret(char *desc, LSA_R_OPEN_SECRET *r_o, prs_struct *ps, int depth);
+void lsa_io_secret_value(char *desc, LSA_SECRET_VALUE *value, prs_struct *ps, int depth);
+void lsa_io_secret_info(char *desc, LSA_SECRET_INFO *info, prs_struct *ps, int depth);
+void make_q_query_secret(LSA_Q_QUERY_SECRET *q_q, POLICY_HND *pol);
+void lsa_io_q_query_secret(char *desc, LSA_Q_QUERY_SECRET *q_q, prs_struct *ps, int depth);
+void lsa_io_r_query_secret(char *desc, LSA_R_QUERY_SECRET *r_q, prs_struct *ps, int depth);
void lsa_io_q_enum_trust_dom(char *desc, LSA_Q_ENUM_TRUST_DOM *q_e, prs_struct *ps, int depth);
void make_r_enum_trust_dom(LSA_R_ENUM_TRUST_DOM *r_e,
uint32 enum_context, char *domain_name, DOM_SID *domain_sid,
@@ -1917,6 +1897,8 @@ void make_dom_sid2(DOM_SID2 *sid2, DOM_SID *sid);
void smb_io_dom_sid2(char *desc, DOM_SID2 *sid, prs_struct *ps, int depth);
void make_str_hdr(STRHDR *hdr, int max_len, int len, uint32 buffer);
void smb_io_strhdr(char *desc, STRHDR *hdr, prs_struct *ps, int depth);
+void make_strhdr2(STRHDR2 *hdr, uint32 max_len, uint32 len, uint32 buffer);
+void smb_io_strhdr2(char *desc, STRHDR2 *hdr, prs_struct *ps, int depth);
void make_uni_hdr(UNIHDR *hdr, int max_len, int len, uint32 buffer);
void smb_io_unihdr(char *desc, UNIHDR *hdr, prs_struct *ps, int depth);
void make_buf_hdr(BUFHDR *hdr, int max_len, int len);
@@ -2745,6 +2727,7 @@ BOOL api_wkssvc_rpc(pipes_struct *p, prs_struct *data);
void cmd_lsa_query_info(struct client_info *info);
void cmd_lsa_lookup_names(struct client_info *info);
void cmd_lsa_lookup_sids(struct client_info *info);
+void cmd_lsa_query_secret(struct client_info *info);
/*The following definitions come from rpcclient/cmd_netlogon.c */
diff --git a/source3/include/rpc_lsa.h b/source3/include/rpc_lsa.h
index fd60423566..6129c3bf01 100644
--- a/source3/include/rpc_lsa.h
+++ b/source3/include/rpc_lsa.h
@@ -46,7 +46,8 @@ enum SID_NAME_USE
#define LSA_LOOKUPSIDS 0x0f
#define LSA_OPENPOLICY 0x06
#define LSA_OPENPOLICY2 0x2c
-#define LSA_OPENSECRET 0x1C
+#define LSA_OPENSECRET 0x1c
+#define LSA_QUERYSECRET 0x1e
#define LSA_MAX_GROUPS 32
#define LSA_MAX_SIDS 32
@@ -152,6 +153,63 @@ typedef struct lsa_r_query_info
} LSA_R_QUERY_INFO;
+/* LSA_Q_OPEN_SECRET - LSA Open Secret */
+typedef struct lsa_q_open_secret_info
+{
+ POLICY_HND pol;
+ UNIHDR hdr_secret;
+ UNISTR2 uni_secret;
+
+ uint32 des_access; /* desired access attributes */
+
+} LSA_Q_OPEN_SECRET;
+
+/* LSA_R_OPEN_SECRET - response to LSA Open Secret */
+typedef struct lsa_r_open_secret_info
+{
+ POLICY_HND pol;
+ uint32 status;
+
+} LSA_R_OPEN_SECRET;
+
+typedef struct lsa_secret_value_info
+{
+ uint32 ptr_secret;
+ STRHDR2 hdr_secret;
+ STRING2 secret;
+
+} LSA_SECRET_VALUE;
+
+typedef struct lsa_secret_info_info
+{
+ uint32 ptr_value;
+ LSA_SECRET_VALUE value;
+
+ uint32 ptr_update;
+ NTTIME last_update; /* N.B. 64-bit alignment? */
+
+} LSA_SECRET_INFO;
+
+/* LSA_Q_QUERY_SECRET - LSA Query Secret */
+typedef struct lsa_q_query_secret_info
+{
+ POLICY_HND pol;
+
+ LSA_SECRET_INFO info; /* [in, out] */
+ LSA_SECRET_INFO oldinfo;
+
+} LSA_Q_QUERY_SECRET;
+
+/* LSA_R_QUERY_SECRET - response to LSA Query Secret */
+typedef struct lsa_r_query_secret_info
+{
+ LSA_SECRET_INFO info;
+ LSA_SECRET_INFO oldinfo;
+
+ uint32 status;
+
+} LSA_R_QUERY_SECRET;
+
/* LSA_Q_ENUM_TRUST_DOM - LSA enumerate trusted domains */
typedef struct lsa_enum_trust_dom_info
{
diff --git a/source3/include/rpc_misc.h b/source3/include/rpc_misc.h
index ff0d2cc49d..1c5689dd87 100644
--- a/source3/include/rpc_misc.h
+++ b/source3/include/rpc_misc.h
@@ -96,6 +96,15 @@ typedef struct header_info
} STRHDR;
+/* STRHDR2 - string header, 32-bit lengths */
+typedef struct header2_info
+{
+ uint32 str_str_len;
+ uint32 str_max_len;
+ uint32 buffer;
+
+} STRHDR2;
+
/* UNIHDR - unicode string header */
typedef struct unihdr_info
{
diff --git a/source3/rpc_client/cli_lsarpc.c b/source3/rpc_client/cli_lsarpc.c
index 751a84aaaa..ca3ee49d3b 100644
--- a/source3/rpc_client/cli_lsarpc.c
+++ b/source3/rpc_client/cli_lsarpc.c
@@ -99,6 +99,121 @@ BOOL lsa_open_policy(struct cli_state *cli, uint16 fnum,
}
/****************************************************************************
+do a LSA Open Secret
+****************************************************************************/
+BOOL lsa_open_secret(struct cli_state *cli, uint16 fnum,
+ POLICY_HND *hnd_pol, char *secret_name, uint32 des_access,
+ POLICY_HND *hnd_secret)
+{
+ prs_struct rbuf;
+ prs_struct buf;
+ LSA_Q_OPEN_SECRET q_o;
+ BOOL valid_pol;
+
+ if (hnd_pol == NULL) return False;
+
+ prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
+ prs_init(&rbuf, 0 , 4, SAFETY_MARGIN, True );
+
+ /* create and send a MSRPC command with api LSA_OPENSECRET */
+
+ DEBUG(4,("LSA Open Secret\n"));
+
+ make_q_open_secret(&q_o, hnd_pol, secret_name, des_access);
+
+ /* turn parameters into data stream */
+ lsa_io_q_open_secret("", &q_o, &buf, 0);
+
+ /* send the data on \PIPE\ */
+ if (rpc_api_pipe_req(cli, fnum, LSA_OPENSECRET, &buf, &rbuf))
+ {
+ LSA_R_OPEN_SECRET r_o;
+ BOOL p;
+
+ lsa_io_r_open_secret("", &r_o, &rbuf, 0);
+ p = rbuf.offset != 0;
+
+ if (p && r_o.status != 0)
+ {
+ /* report error code */
+ DEBUG(0,("LSA_OPENSECRET: %s\n", get_nt_error_msg(r_o.status)));
+ p = False;
+ }
+
+ if (p)
+ {
+ /* ok, at last: we're happy. return the policy handle */
+ memcpy(hnd_secret, r_o.pol.data, sizeof(hnd_secret->data));
+ valid_pol = True;
+ }
+ }
+
+ prs_mem_free(&rbuf);
+ prs_mem_free(&buf );
+
+ return valid_pol;
+}
+
+/****************************************************************************
+do a LSA Query Secret
+****************************************************************************/
+BOOL lsa_query_secret(struct cli_state *cli, uint16 fnum,
+ POLICY_HND *pol, unsigned char secret[24],
+ NTTIME *lastupdate)
+{
+ prs_struct rbuf;
+ prs_struct buf;
+ LSA_Q_QUERY_SECRET q_q;
+ BOOL valid_info = False;
+
+ if (pol == NULL) return False;
+
+ prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
+ prs_init(&rbuf, 0 , 4, SAFETY_MARGIN, True );
+
+ /* create and send a MSRPC command with api LSA_QUERYSECRET */
+
+ DEBUG(4,("LSA Query Secret\n"));
+
+ make_q_query_secret(&q_q, pol);
+
+ /* turn parameters into data stream */
+ lsa_io_q_query_secret("", &q_q, &buf, 0);
+
+ /* send the data on \PIPE\ */
+ if (rpc_api_pipe_req(cli, fnum, LSA_QUERYSECRET, &buf, &rbuf))
+ {
+ LSA_R_QUERY_SECRET r_q;
+ BOOL p;
+
+ lsa_io_r_query_secret("", &r_q, &rbuf, 0);
+ p = rbuf.offset != 0;
+
+ if (p && r_q.status != 0)
+ {
+ /* report error code */
+ DEBUG(0,("LSA_QUERYSECRET: %s\n", get_nt_error_msg(r_q.status)));
+ p = False;
+ }
+
+ if (p && (r_q.info.ptr_value != 0) &&
+ (r_q.info.value.ptr_secret != 0) &&
+ (r_q.info.ptr_update != 0))
+ {
+ memcpy(secret, r_q.info.value.secret.buffer, 24);
+ memcpy(lastupdate, &(r_q.info.last_update), sizeof(NTTIME));
+ valid_info = True;
+ }
+ }
+
+ prs_mem_free(&rbuf);
+ prs_mem_free(&buf );
+
+ return valid_info;
+}
+
+
+/****************************************************************************
do a LSA Lookup Names
****************************************************************************/
BOOL lsa_lookup_names(struct cli_state *cli, uint16 fnum,
diff --git a/source3/rpc_parse/parse_lsa.c b/source3/rpc_parse/parse_lsa.c
index cb88e71536..c01664c15c 100644
--- a/source3/rpc_parse/parse_lsa.c
+++ b/source3/rpc_parse/parse_lsa.c
@@ -381,6 +381,171 @@ void lsa_io_q_query(char *desc, LSA_Q_QUERY_INFO *q_q, prs_struct *ps, int dept
}
/*******************************************************************
+makes an LSA_Q_OPEN_SECRET structure.
+********************************************************************/
+void make_q_open_secret(LSA_Q_OPEN_SECRET *q_o, POLICY_HND *pol_hnd,
+ char *secret_name, uint32 desired_access)
+{
+ int len = strlen(secret_name);
+
+ if (q_o == NULL) return;
+
+ DEBUG(5,("make_q_open_secret"));
+
+ memcpy(&(q_o->pol), pol_hnd, sizeof(q_o->pol));
+
+ make_uni_hdr(&(q_o->hdr_secret), len, len, 1);
+ make_unistr2(&(q_o->uni_secret), secret_name, len);
+
+ q_o->des_access = desired_access;
+}
+
+/*******************************************************************
+reads or writes an LSA_Q_OPEN_SECRET structure.
+********************************************************************/
+void lsa_io_q_open_secret(char *desc, LSA_Q_OPEN_SECRET *q_o, prs_struct *ps, int depth)
+{
+ if (q_o == NULL) return;
+
+ prs_debug(ps, depth, desc, "lsa_io_q_open_secret");
+ depth++;
+
+ smb_io_pol_hnd("", &(q_o->pol), ps, depth);
+
+ prs_align(ps);
+ smb_io_unihdr ("", &(q_o->hdr_secret), ps, depth);
+ smb_io_unistr2("", &(q_o->uni_secret), 1, ps, depth);
+
+ prs_align(ps);
+ prs_uint32("des_access", ps, depth, &(q_o->des_access));
+}
+
+/*******************************************************************
+reads or writes an LSA_R_OPEN_SECRET structure.
+********************************************************************/
+void lsa_io_r_open_secret(char *desc, LSA_R_OPEN_SECRET *r_o, prs_struct *ps, int depth)
+{
+ if (r_o == NULL) return;
+
+ prs_debug(ps, depth, desc, "lsa_io_r_open_secret");
+ depth++;
+
+ smb_io_pol_hnd("", &(r_o->pol), ps, depth);
+
+ prs_uint32("status", ps, depth, &(r_o->status));
+}
+
+/*******************************************************************
+reads or writes an LSA_SECRET_VALUE structure.
+********************************************************************/
+void lsa_io_secret_value(char *desc, LSA_SECRET_VALUE *value, prs_struct *ps, int depth)
+{
+ if (value == NULL) return;
+
+ prs_debug(ps, depth, desc, "lsa_io_secret_value");
+ depth++;
+
+ prs_align(ps);
+ prs_uint32("ptr_secret", ps, depth, &(value->ptr_secret));
+
+ if (value->ptr_secret == 0)
+ {
+ return;
+ }
+
+ smb_io_strhdr2("hdr_secret", &(value->hdr_secret), ps, depth);
+ smb_io_string2("secret" , &(value->secret ),
+ value->hdr_secret.buffer, ps, depth);
+}
+
+/*******************************************************************
+reads or writes an LSA_SECRET_INFO structure.
+********************************************************************/
+void lsa_io_secret_info(char *desc, LSA_SECRET_INFO *info, prs_struct *ps, int depth)
+{
+ if (info == NULL) return;
+
+ prs_debug(ps, depth, desc, "lsa_io_secret_info");
+ depth++;
+
+ prs_align(ps);
+ prs_uint32("ptr_value ", ps, depth, &(info->ptr_value ));
+
+ if (info->ptr_value != 0)
+ {
+ lsa_io_secret_value("", &(info->value), ps, depth);
+ }
+
+ prs_align(ps);
+ prs_uint32("ptr_update", ps, depth, &(info->ptr_update));
+
+ if (info->ptr_update != 0)
+ {
+ ps->align = 8;
+ prs_align(ps);
+ ps->align = 4;
+
+ smb_io_time("last_update", &(info->last_update), ps, depth);
+ }
+}
+
+/*******************************************************************
+makes an LSA_Q_QUERY_SECRET structure.
+********************************************************************/
+void make_q_query_secret(LSA_Q_QUERY_SECRET *q_q, POLICY_HND *pol)
+{
+ if (q_q == NULL) return;
+
+ DEBUG(5,("make_q_query_secret"));
+
+ memcpy(&(q_q->pol), pol, sizeof(q_q->pol));
+
+ /* Want secret */
+ q_q->info.ptr_value = 1;
+ q_q->info.value.ptr_secret = 0;
+
+ /* Want last change time */
+ q_q->info.ptr_update = 1;
+
+ /* Don't care about old info */
+ q_q->oldinfo.ptr_value = 0;
+ q_q->oldinfo.ptr_update = 0;
+}
+
+/*******************************************************************
+reads or writes an LSA_Q_QUERY_SECRET structure.
+********************************************************************/
+void lsa_io_q_query_secret(char *desc, LSA_Q_QUERY_SECRET *q_q, prs_struct *ps, int depth)
+{
+ if (q_q == NULL) return;
+
+ prs_debug(ps, depth, desc, "lsa_io_q_query_secret");
+ depth++;
+
+ smb_io_pol_hnd("", &(q_q->pol), ps, depth);
+
+ lsa_io_secret_info("", &(q_q->info ), ps, depth);
+ lsa_io_secret_info("", &(q_q->oldinfo), ps, depth);
+}
+
+/*******************************************************************
+reads or writes an LSA_Q_QUERY_SECRET structure.
+********************************************************************/
+void lsa_io_r_query_secret(char *desc, LSA_R_QUERY_SECRET *r_q, prs_struct *ps, int depth)
+{
+ if (r_q == NULL) return;
+
+ prs_debug(ps, depth, desc, "lsa_io_r_query_secret");
+ depth++;
+
+ lsa_io_secret_info("", &(r_q->info ), ps, depth);
+ lsa_io_secret_info("", &(r_q->oldinfo), ps, depth);
+
+ prs_align(ps);
+ prs_uint32("status", ps, depth, &(r_q->status));
+}
+
+/*******************************************************************
reads or writes an LSA_Q_ENUM_TRUST_DOM structure.
********************************************************************/
void lsa_io_q_enum_trust_dom(char *desc, LSA_Q_ENUM_TRUST_DOM *q_e, prs_struct *ps, int depth)
diff --git a/source3/rpc_parse/parse_misc.c b/source3/rpc_parse/parse_misc.c
index 1656c39139..e4b7578e67 100644
--- a/source3/rpc_parse/parse_misc.c
+++ b/source3/rpc_parse/parse_misc.c
@@ -205,6 +205,37 @@ void smb_io_strhdr(char *desc, STRHDR *hdr, prs_struct *ps, int depth)
}
/*******************************************************************
+creates a STRHDR2 structure.
+********************************************************************/
+void make_strhdr2(STRHDR2 *hdr, uint32 max_len, uint32 len, uint32 buffer)
+{
+ hdr->str_max_len = max_len;
+ hdr->str_str_len = len;
+ hdr->buffer = buffer;
+}
+
+/*******************************************************************
+reads or writes a STRHDR2 structure.
+********************************************************************/
+void smb_io_strhdr2(char *desc, STRHDR2 *hdr, prs_struct *ps, int depth)
+{
+ if (hdr == NULL) return;
+
+ prs_debug(ps, depth, desc, "smb_io_strhdr");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("str_str_len", ps, depth, &(hdr->str_str_len));
+ prs_uint32("str_max_len", ps, depth, &(hdr->str_max_len));
+ prs_uint32("buffer ", ps, depth, &(hdr->buffer ));
+
+ /* oops! XXXX maybe issue a warning that this is happening... */
+ if (hdr->str_max_len > MAX_STRINGLEN) hdr->str_max_len = MAX_STRINGLEN;
+ if (hdr->str_str_len > MAX_STRINGLEN) hdr->str_str_len = MAX_STRINGLEN;
+}
+
+/*******************************************************************
creates a UNIHDR structure.
********************************************************************/
void make_uni_hdr(UNIHDR *hdr, int max_len, int len, uint32 buffer)
diff --git a/source3/rpcclient/cmd_lsarpc.c b/source3/rpcclient/cmd_lsarpc.c
index be148a7f1d..a0d60037ec 100644
--- a/source3/rpcclient/cmd_lsarpc.c
+++ b/source3/rpcclient/cmd_lsarpc.c
@@ -309,3 +309,72 @@ void cmd_lsa_lookup_sids(struct client_info *info)
}
}
+/****************************************************************************
+nt lsa query
+****************************************************************************/
+void cmd_lsa_query_secret(struct client_info *info)
+{
+ uint16 nt_pipe_fnum;
+ fstring srv_name;
+ BOOL res = True;
+ BOOL res1;
+ int i;
+
+ POLICY_HND hnd_secret;
+ fstring secret_name;
+ unsigned char enc_secret[24];
+ NTTIME last_update;
+
+ if (!next_token(NULL, secret_name, NULL, sizeof(secret_name)))
+ {
+ fprintf(out_hnd, "querysecret <secret name>\n");
+ return;
+ }
+
+ fstrcpy(srv_name, "\\\\");
+ fstrcat(srv_name, info->myhostname);
+ strupper(srv_name);
+
+ DEBUG(4,("cmd_lsa_query_info: server:%s\n", srv_name));
+
+ /* open LSARPC session. */
+ res = res ? cli_nt_session_open(smb_cli, PIPE_LSARPC, &nt_pipe_fnum) : False;
+
+ /* lookup domain controller; receive a policy handle */
+ res = res ? lsa_open_policy(smb_cli, nt_pipe_fnum,
+ srv_name,
+ &info->dom.lsa_info_pol, False) : False;
+
+ /* lookup domain controller; receive a policy handle */
+ res = res ? lsa_open_secret(smb_cli, nt_pipe_fnum,
+ &info->dom.lsa_info_pol,
+ secret_name, 0x20003, &hnd_secret) : False;
+
+ res1 = res ? lsa_query_secret(smb_cli, nt_pipe_fnum,
+ &hnd_secret, enc_secret, &last_update) : False;
+
+ res = res ? lsa_close(smb_cli, nt_pipe_fnum, &hnd_secret) : False;
+
+ res = res ? lsa_close(smb_cli, nt_pipe_fnum, &info->dom.lsa_info_pol) : False;
+
+ /* close the session */
+ cli_nt_session_close(smb_cli, nt_pipe_fnum);
+
+ if (res1)
+ {
+ fprintf(out_hnd, "\tValue (encrypted): ");
+ for (i = 0; i < 24; i++)
+ {
+ fprintf(out_hnd, "%02X", enc_secret[i]);
+ }
+
+ fprintf(out_hnd, "\n\tLast Updated : %s\n\n",
+ http_timestring(nt_time_to_unix(&last_update)));
+ }
+ else
+ {
+ fprintf(out_hnd, "LSA Query Secret: failed\n");
+ }
+}
+
+
diff --git a/source3/rpcclient/rpcclient.c b/source3/rpcclient/rpcclient.c
index a9719b143b..fb520004da 100644
--- a/source3/rpcclient/rpcclient.c
+++ b/source3/rpcclient/rpcclient.c
@@ -140,6 +140,7 @@ struct
{"enumaliases",cmd_sam_enum_aliases, "SAM Aliases Database Query (experimental!)"},
{"enumgroups", cmd_sam_enum_groups, "SAM Group Database Query (experimental!)"},
{"samgroups", cmd_sam_query_dominfo, "SAM Query Domain Info(experimental!)"},
+ {"querysecret", cmd_lsa_query_secret, "LSA Query Secret (developer use)"},
{"quit", cmd_quit, "logoff the server"},
{"q", cmd_quit, "logoff the server"},
{"exit", cmd_quit, "logoff the server"},