1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-23 17:34:34 +03:00

r7391: - Added client-support for various lsa_query_trust_dom_info-calls and a

rpcclient-tester for some info-levels.

  Jerry, I tried to adopt to prs_pointer() where possible and to not
  interfere with your work for usrmgr.

- Add "net rpc trustdom vampire"-tool.

  This allows to retrieve Interdomain Trust(ed)-Relationships from
  NT4-Servers including cleartext-passwords (still stored in the local
  secrets.tdb).

  The net-hook was done in cooperation with Lars Mueller
  <lmuelle@suse.de>.

  To vampire trusted domains simply call:

        net rpc trustdom vampire -S nt4dc -Uadmin%pass

Guenther
(This used to be commit 5125852939)
This commit is contained in:
Günther Deschner 2005-06-08 13:59:03 +00:00 committed by Gerald (Jerry) Carter
parent eeca550731
commit 4bc39f05b7
7 changed files with 1146 additions and 18 deletions

View File

@ -60,7 +60,7 @@
#define LSA_GETSYSTEMACCOUNT 0x17
#define LSA_SETSYSTEMACCOUNT 0x18
#define LSA_OPENTRUSTDOM 0x19 /* TODO: implement this one -- jerry */
#define LSA_QUERYTRUSTDOM 0x1a
#define LSA_QUERYTRUSTDOMINFO 0x1a
#define LSA_SETINFOTRUSTDOM 0x1b
#define LSA_OPENSECRET 0x1c /* TODO: implement this one -- jerry */
#define LSA_SETSECRET 0x1d /* TODO: implement this one -- jerry */
@ -73,7 +73,7 @@
#define LSA_ENUMACCTRIGHTS 0x24
#define LSA_ADDACCTRIGHTS 0x25
#define LSA_REMOVEACCTRIGHTS 0x26
#define LSA_QUERYTRUSTDOMINFO 0x27
#define LSA_QUERYTRUSTDOMINFOBYSID 0x27
#define LSA_SETTRUSTDOMINFO 0x28
#define LSA_DELETETRUSTDOM 0x29
#define LSA_STOREPRIVDATA 0x2a
@ -81,6 +81,8 @@
#define LSA_OPENPOLICY2 0x2c
#define LSA_UNK_GET_CONNUSER 0x2d /* LsaGetConnectedCredentials ? */
#define LSA_QUERYINFO2 0x2e
#define LSA_QUERYTRUSTDOMINFOBYNAME 0x30
#define LSA_OPENTRUSTDOMBYNAME 0x37
/* XXXX these are here to get a compile! */
#define LSA_LOOKUPRIDS 0xFD
@ -724,16 +726,27 @@ typedef struct lsa_r_removeprivs
} LSA_R_REMOVEPRIVS;
/*******************************************************/
#if 0 /* jerry, I think this not correct - gd */
typedef struct {
POLICY_HND handle;
uint32 count; /* ??? this is what ethereal calls it */
DOM_SID sid;
} LSA_Q_OPEN_TRUSTED_DOMAIN;
#endif
/* LSA_Q_OPEN_TRUSTED_DOMAIN - LSA Query Open Trusted Domain */
typedef struct lsa_q_open_trusted_domain
{
POLICY_HND pol; /* policy handle */
DOM_SID2 sid; /* domain sid */
uint32 access_mask; /* access mask */
} LSA_Q_OPEN_TRUSTED_DOMAIN;
/* LSA_R_OPEN_TRUSTED_DOMAIN - response to LSA Query Open Trusted Domain */
typedef struct {
POLICY_HND handle;
NTSTATUS status;
POLICY_HND handle; /* trustdom policy handle */
NTSTATUS status; /* return code */
} LSA_R_OPEN_TRUSTED_DOMAIN;
@ -810,5 +823,138 @@ typedef struct {
NTSTATUS status;
} LSA_R_SET_SECRET;
/* LSA_Q_QUERY_TRUSTED_DOMAIN_INFO - LSA query trusted domain info */
typedef struct lsa_query_trusted_domain_info
{
POLICY_HND pol; /* policy handle */
uint16 info_class; /* info class */
} LSA_Q_QUERY_TRUSTED_DOMAIN_INFO;
/* LSA_Q_QUERY_TRUSTED_DOMAIN_INFO_BY_SID - LSA query trusted domain info */
typedef struct lsa_query_trusted_domain_info_by_sid
{
POLICY_HND pol; /* policy handle */
DOM_SID2 dom_sid; /* domain sid */
uint16 info_class; /* info class */
} LSA_Q_QUERY_TRUSTED_DOMAIN_INFO_BY_SID;
/* LSA_Q_QUERY_TRUSTED_DOMAIN_INFO_BY_NAME - LSA query trusted domain info */
typedef struct lsa_query_trusted_domain_info_by_name
{
POLICY_HND pol; /* policy handle */
LSA_STRING domain_name; /* domain name */
uint16 info_class; /* info class */
} LSA_Q_QUERY_TRUSTED_DOMAIN_INFO_BY_NAME;
typedef struct trusted_domain_info_name {
LSA_STRING netbios_name;
} TRUSTED_DOMAIN_INFO_NAME;
typedef struct trusted_domain_info_posix_offset {
uint32 posix_offset;
} TRUSTED_DOMAIN_INFO_POSIX_OFFSET;
typedef struct lsa_data_buf {
uint32 size;
uint32 offset;
uint32 length;
uint8 *data;
} LSA_DATA_BUF;
typedef struct lsa_data_buf_hdr {
uint32 length;
uint32 size;
uint32 data_ptr;
} LSA_DATA_BUF_HDR;
typedef struct lsa_data_buf2 {
uint32 size;
uint8 *data;
} LSA_DATA_BUF2;
typedef struct trusted_domain_info_password {
uint32 ptr_password;
uint32 ptr_old_password;
LSA_DATA_BUF_HDR password_hdr;
LSA_DATA_BUF_HDR old_password_hdr;
LSA_DATA_BUF password;
LSA_DATA_BUF old_password;
} TRUSTED_DOMAIN_INFO_PASSWORD;
typedef struct trusted_domain_info_basic {
LSA_STRING netbios_name;
DOM_SID2 sid;
} TRUSTED_DOMAIN_INFO_BASIC;
typedef struct trusted_domain_info_ex {
LSA_STRING domain_name;
LSA_STRING netbios_name;
DOM_SID2 sid;
uint32 trust_direction;
uint32 trust_type;
uint32 trust_attributes;
} TRUSTED_DOMAIN_INFO_EX;
typedef struct trust_domain_info_buffer {
NTTIME last_update_time;
uint32 secret_type;
LSA_DATA_BUF2 data;
} LSA_TRUSTED_DOMAIN_INFO_BUFFER;
typedef struct trusted_domain_info_auth_info {
uint32 incoming_count;
LSA_TRUSTED_DOMAIN_INFO_BUFFER incoming_current_auth_info;
LSA_TRUSTED_DOMAIN_INFO_BUFFER incoming_previous_auth_info;
uint32 outgoing_count;
LSA_TRUSTED_DOMAIN_INFO_BUFFER outgoing_current_auth_info;
LSA_TRUSTED_DOMAIN_INFO_BUFFER outgoing_previous_auth_info;
} TRUSTED_DOMAIN_INFO_AUTH_INFO;
typedef struct trusted_domain_info_full_info {
TRUSTED_DOMAIN_INFO_EX info_ex;
TRUSTED_DOMAIN_INFO_POSIX_OFFSET posix_offset;
TRUSTED_DOMAIN_INFO_AUTH_INFO auth_info;
} TRUSTED_DOMAIN_INFO_FULL_INFO;
typedef struct trusted_domain_info_11 {
TRUSTED_DOMAIN_INFO_EX info_ex;
LSA_DATA_BUF2 data1;
} TRUSTED_DOMAIN_INFO_11;
typedef struct trusted_domain_info_all {
TRUSTED_DOMAIN_INFO_EX info_ex;
LSA_DATA_BUF2 data1;
TRUSTED_DOMAIN_INFO_POSIX_OFFSET posix_offset;
TRUSTED_DOMAIN_INFO_AUTH_INFO auth_info;
} TRUSTED_DOMAIN_INFO_ALL;
/* LSA_TRUSTED_DOMAIN_INFO */
typedef union lsa_trusted_domain_info
{
uint16 info_class;
TRUSTED_DOMAIN_INFO_NAME name;
/* deprecated - gd
TRUSTED_DOMAIN_INFO_CONTROLLERS_INFO controllers; */
TRUSTED_DOMAIN_INFO_POSIX_OFFSET posix_offset;
TRUSTED_DOMAIN_INFO_PASSWORD password;
TRUSTED_DOMAIN_INFO_BASIC basic;
TRUSTED_DOMAIN_INFO_EX info_ex;
TRUSTED_DOMAIN_INFO_AUTH_INFO auth_info;
TRUSTED_DOMAIN_INFO_FULL_INFO full_info;
TRUSTED_DOMAIN_INFO_11 info11;
TRUSTED_DOMAIN_INFO_ALL info_all;
} LSA_TRUSTED_DOMAIN_INFO;
/* LSA_R_QUERY_TRUSTED_DOMAIN_INFO - LSA query trusted domain info */
typedef struct r_lsa_query_trusted_domain_info
{
LSA_TRUSTED_DOMAIN_INFO *info;
NTSTATUS status;
} LSA_R_QUERY_TRUSTED_DOMAIN_INFO;
#endif /* _RPC_LSA_H */

View File

@ -583,3 +583,69 @@ void sess_crypt_blob(DATA_BLOB *out, const DATA_BLOB *in, const DATA_BLOB *sessi
memcpy(&out->data[i], bout, MIN(8, in->length-i));
}
}
/* Decrypts password-blob with session-key
* @param pass password for session-key
* @param data_in DATA_BLOB encrypted password
*
* Returns cleartext password in CH_UNIX
* Caller must free the returned string
*/
char *decrypt_trustdom_secret(const char *pass, DATA_BLOB *data_in)
{
DATA_BLOB data_out, sess_key;
uchar nt_hash[16];
uint32_t length;
uint32_t version;
fstring cleartextpwd;
if (!data_in || !pass)
return NULL;
/* generate md4 password-hash derived from the NT UNICODE password */
E_md4hash(pass, nt_hash);
/* hashed twice with md4 */
mdfour(nt_hash, nt_hash, 16);
/* 16-Byte session-key */
sess_key = data_blob(nt_hash, 16);
if (sess_key.data == NULL)
return NULL;
data_out = data_blob(NULL, data_in->length);
if (data_out.data == NULL)
return NULL;
/* decrypt with des3 */
sess_crypt_blob(&data_out, data_in, &sess_key, 0);
/* 4 Byte length, 4 Byte version */
length = IVAL(data_out.data, 0);
version = IVAL(data_out.data, 4);
if (length > data_in->length - 8) {
DEBUG(0,("decrypt_trustdom_secret: invalid length (%d)\n", length));
return NULL;
}
if (version != 1) {
DEBUG(0,("decrypt_trustdom_secret: unknown version number (%d)\n", version));
return NULL;
}
rpcstr_pull(cleartextpwd, data_out.data + 8, sizeof(fstring), length, 0 );
#ifdef DEBUG_PASSWORD
DEBUG(100,("decrypt_trustdom_secret: length is: %d, version is: %d, password is: %s\n",
length, version, cleartextpwd));
#endif
data_blob_free(&data_out);
data_blob_free(&sess_key);
return SMB_STRDUP(cleartextpwd);
}

View File

@ -1452,4 +1452,199 @@ Error was : %s.\n", remote_machine, cli_errstr(&cli) ));
#endif
NTSTATUS cli_lsa_open_trusted_domain(struct cli_state *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *pol, DOM_SID *dom_sid, uint32 access_mask,
POLICY_HND *trustdom_pol)
{
prs_struct qbuf, rbuf;
LSA_Q_OPEN_TRUSTED_DOMAIN q;
LSA_R_OPEN_TRUSTED_DOMAIN r;
NTSTATUS result;
ZERO_STRUCT(q);
ZERO_STRUCT(r);
/* Initialise parse structures */
prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
/* Initialise input parameters */
init_lsa_q_open_trusted_domain(&q, pol, dom_sid, access_mask);
/* Marshall data and send request */
if (!lsa_io_q_open_trusted_domain("", &q, &qbuf, 0) ||
!rpc_api_pipe_req(cli, PI_LSARPC, LSA_OPENTRUSTDOM, &qbuf, &rbuf)) {
result = NT_STATUS_UNSUCCESSFUL;
goto done;
}
/* Unmarshall response */
if (!lsa_io_r_open_trusted_domain("", &r, &rbuf, 0)) {
result = NT_STATUS_UNSUCCESSFUL;
goto done;
}
/* Return output parameters */
if (NT_STATUS_IS_OK(result = r.status)) {
*trustdom_pol = r.handle;
}
done:
prs_mem_free(&qbuf);
prs_mem_free(&rbuf);
return result;
}
NTSTATUS cli_lsa_query_trusted_domain_info(struct cli_state *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *pol,
uint16 info_class, DOM_SID *dom_sid,
LSA_TRUSTED_DOMAIN_INFO **info)
{
prs_struct qbuf, rbuf;
LSA_Q_QUERY_TRUSTED_DOMAIN_INFO q;
LSA_R_QUERY_TRUSTED_DOMAIN_INFO r;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
ZERO_STRUCT(q);
ZERO_STRUCT(r);
/* Initialise parse structures */
prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
/* Marshall data and send request */
init_q_query_trusted_domain_info(&q, pol, info_class);
if (!lsa_io_q_query_trusted_domain_info("", &q, &qbuf, 0) ||
!rpc_api_pipe_req(cli, PI_LSARPC, LSA_QUERYTRUSTDOMINFO, &qbuf, &rbuf)) {
result = NT_STATUS_UNSUCCESSFUL;
goto done;
}
/* Unmarshall response */
if (!lsa_io_r_query_trusted_domain_info("", &r, &rbuf, 0)) {
result = NT_STATUS_UNSUCCESSFUL;
goto done;
}
if (!NT_STATUS_IS_OK(result = r.status)) {
goto done;
}
*info = r.info;
done:
prs_mem_free(&qbuf);
prs_mem_free(&rbuf);
return result;
}
NTSTATUS cli_lsa_query_trusted_domain_info_by_sid(struct cli_state *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *pol,
uint16 info_class, DOM_SID *dom_sid,
LSA_TRUSTED_DOMAIN_INFO **info)
{
prs_struct qbuf, rbuf;
LSA_Q_QUERY_TRUSTED_DOMAIN_INFO_BY_SID q;
LSA_R_QUERY_TRUSTED_DOMAIN_INFO r;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
ZERO_STRUCT(q);
ZERO_STRUCT(r);
/* Initialise parse structures */
prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
/* Marshall data and send request */
init_q_query_trusted_domain_info_by_sid(&q, pol, info_class, dom_sid);
if (!lsa_io_q_query_trusted_domain_info_by_sid("", &q, &qbuf, 0) ||
!rpc_api_pipe_req(cli, PI_LSARPC, LSA_QUERYTRUSTDOMINFOBYSID, &qbuf, &rbuf)) {
result = NT_STATUS_UNSUCCESSFUL;
goto done;
}
/* Unmarshall response */
if (!lsa_io_r_query_trusted_domain_info("", &r, &rbuf, 0)) {
result = NT_STATUS_UNSUCCESSFUL;
goto done;
}
if (!NT_STATUS_IS_OK(result = r.status)) {
goto done;
}
*info = r.info;
done:
prs_mem_free(&qbuf);
prs_mem_free(&rbuf);
return result;
}
NTSTATUS cli_lsa_query_trusted_domain_info_by_name(struct cli_state *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *pol,
uint16 info_class, const char *domain_name,
LSA_TRUSTED_DOMAIN_INFO **info)
{
prs_struct qbuf, rbuf;
LSA_Q_QUERY_TRUSTED_DOMAIN_INFO_BY_NAME q;
LSA_R_QUERY_TRUSTED_DOMAIN_INFO r;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
ZERO_STRUCT(q);
ZERO_STRUCT(r);
/* Initialise parse structures */
prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
/* Marshall data and send request */
init_q_query_trusted_domain_info_by_name(&q, pol, info_class, domain_name);
if (!lsa_io_q_query_trusted_domain_info_by_name("", &q, &qbuf, 0) ||
!rpc_api_pipe_req(cli, PI_LSARPC, LSA_QUERYTRUSTDOMINFOBYNAME, &qbuf, &rbuf)) {
result = NT_STATUS_UNSUCCESSFUL;
goto done;
}
/* Unmarshall response */
if (!lsa_io_r_query_trusted_domain_info("", &r, &rbuf, 0)) {
result = NT_STATUS_UNSUCCESSFUL;
goto done;
}
if (!NT_STATUS_IS_OK(result = r.status)) {
goto done;
}
*info = r.info;
done:
prs_mem_free(&qbuf);
prs_mem_free(&rbuf);
return result;
}
/** @} **/

View File

@ -2503,8 +2503,21 @@ BOOL lsa_io_r_remove_acct_rights(const char *desc, LSA_R_REMOVE_ACCT_RIGHTS *out
}
/*******************************************************************
Inits an LSA_Q_OPEN_TRUSTED_DOMAIN structure.
********************************************************************/
void init_lsa_q_open_trusted_domain(LSA_Q_OPEN_TRUSTED_DOMAIN *q, POLICY_HND *hnd, DOM_SID *sid, uint32 desired_access)
{
memcpy(&q->pol, hnd, sizeof(q->pol));
init_dom_sid2(&q->sid, sid);
q->access_mask = desired_access;
}
/*******************************************************************
********************************************************************/
#if 0 /* jerry, I think this not correct - gd */
BOOL lsa_io_q_open_trusted_domain(const char *desc, LSA_Q_OPEN_TRUSTED_DOMAIN *in, prs_struct *ps, int depth)
{
prs_debug(ps, depth, desc, "lsa_io_q_open_trusted_domain");
@ -2524,8 +2537,34 @@ BOOL lsa_io_q_open_trusted_domain(const char *desc, LSA_Q_OPEN_TRUSTED_DOMAIN *i
return True;
}
#endif
/*******************************************************************
Reads or writes an LSA_Q_OPEN_TRUSTED_DOMAIN structure.
********************************************************************/
BOOL lsa_io_q_open_trusted_domain(const char *desc, LSA_Q_OPEN_TRUSTED_DOMAIN *q_o, prs_struct *ps, int depth)
{
prs_debug(ps, depth, desc, "lsa_io_q_open_trusted_domain");
depth++;
if(!prs_align(ps))
return False;
if(!smb_io_pol_hnd("pol", &q_o->pol, ps, depth))
return False;
if(!smb_io_dom_sid2("sid", &q_o->sid, ps, depth))
return False;
if(!prs_uint32("access", ps, depth, &q_o->access_mask))
return False;
return True;
}
/*******************************************************************
Reads or writes an LSA_R_OPEN_TRUSTED_DOMAIN structure.
********************************************************************/
BOOL lsa_io_r_open_trusted_domain(const char *desc, LSA_R_OPEN_TRUSTED_DOMAIN *out, prs_struct *ps, int depth)
@ -2536,7 +2575,7 @@ BOOL lsa_io_r_open_trusted_domain(const char *desc, LSA_R_OPEN_TRUSTED_DOMAIN *o
if(!prs_align(ps))
return False;
if (!smb_io_pol_hnd("", &out->handle, ps, depth))
if (!smb_io_pol_hnd("handle", &out->handle, ps, depth))
return False;
if(!prs_ntstatus("status", ps, depth, &out->status))
@ -2726,3 +2765,308 @@ BOOL lsa_io_r_delete_object(const char *desc, LSA_R_DELETE_OBJECT *out, prs_stru
return True;
}
/*******************************************************************
Inits an LSA_Q_QUERY_TRUSTED_DOMAIN_INFO structure.
********************************************************************/
void init_q_query_trusted_domain_info(LSA_Q_QUERY_TRUSTED_DOMAIN_INFO *q,
POLICY_HND *hnd, uint16 info_class)
{
DEBUG(5, ("init_q_query_trusted_domain_info\n"));
q->pol = *hnd;
q->info_class = info_class;
}
/*******************************************************************
Inits an LSA_Q_QUERY_TRUSTED_DOMAIN_INFO_BY_NAME structure.
********************************************************************/
void init_q_query_trusted_domain_info_by_name(LSA_Q_QUERY_TRUSTED_DOMAIN_INFO_BY_NAME *q,
POLICY_HND *hnd, uint16 info_class,
const char *dom_name)
{
DEBUG(5, ("init_q_query_trusted_domain_info_by_name\n"));
q->pol = *hnd;
init_lsa_string(&q->domain_name, dom_name );
q->info_class = info_class;
}
/*******************************************************************
Inits an LSA_Q_QUERY_TRUSTED_DOMAIN_INFO_BY_SID structure.
********************************************************************/
void init_q_query_trusted_domain_info_by_sid(LSA_Q_QUERY_TRUSTED_DOMAIN_INFO_BY_SID *q,
POLICY_HND *hnd, uint16 info_class,
DOM_SID *dom_sid)
{
DEBUG(5, ("init_q_query_trusted_domain_info_by_sid\n"));
q->pol = *hnd;
init_dom_sid2(&q->dom_sid, dom_sid);
q->info_class = info_class;
}
/*******************************************************************
Reads or writes an LSA_Q_QUERY_TRUSTED_DOMAIN_INFO structure.
********************************************************************/
BOOL lsa_io_q_query_trusted_domain_info(const char *desc,
LSA_Q_QUERY_TRUSTED_DOMAIN_INFO *q_q,
prs_struct *ps, int depth)
{
prs_debug(ps, depth, desc, "lsa_io_q_query_trusted_domain_info");
depth++;
if(!prs_align(ps))
return False;
if(!smb_io_pol_hnd("pol", &q_q->pol, ps, depth))
return False;
if(!prs_uint16("info_class", ps, depth, &q_q->info_class))
return False;
return True;
}
/*******************************************************************
Reads or writes an LSA_Q_QUERY_TRUSTED_DOMAIN_INFO_BY_SID structure.
********************************************************************/
BOOL lsa_io_q_query_trusted_domain_info_by_sid(const char *desc,
LSA_Q_QUERY_TRUSTED_DOMAIN_INFO_BY_SID *q_q,
prs_struct *ps, int depth)
{
prs_debug(ps, depth, desc, "lsa_io_q_query_trusted_domain_info_by_sid");
depth++;
if(!prs_align(ps))
return False;
if(!smb_io_pol_hnd("pol", &q_q->pol, ps, depth))
return False;
if(!prs_align(ps))
return False;
if(!smb_io_dom_sid2("dom_sid", &q_q->dom_sid, ps, depth))
return False;
if(!prs_uint16("info_class", ps, depth, &q_q->info_class))
return False;
return True;
}
/*******************************************************************
Reads or writes an LSA_Q_QUERY_TRUSTED_DOMAIN_INFO_BY_NAME structure.
********************************************************************/
BOOL lsa_io_q_query_trusted_domain_info_by_name(const char *desc,
LSA_Q_QUERY_TRUSTED_DOMAIN_INFO_BY_NAME *q_q,
prs_struct *ps, int depth)
{
prs_debug(ps, depth, desc, "lsa_io_q_query_trusted_domain_info_by_name");
depth++;
if(!prs_align(ps))
return False;
if(!smb_io_pol_hnd("pol", &q_q->pol, ps, depth))
return False;
if(!prs_align(ps))
return False;
if(!smb_io_lsa_string("domain_name", &q_q->domain_name, ps, depth))
return False;
if(!prs_uint16("info_class", ps, depth, &q_q->info_class))
return False;
return True;
}
/*******************************************************************
********************************************************************/
static BOOL smb_io_lsa_data_buf_hdr(const char *desc, LSA_DATA_BUF_HDR *buf_hdr,
prs_struct *ps, int depth)
{
prs_debug(ps, depth, desc, "smb_io_lsa_data_buf_hdr");
depth++;
if(!prs_align(ps))
return False;
if(!prs_uint32("length", ps, depth, &buf_hdr->length))
return False;
if(!prs_uint32("size", ps, depth, &buf_hdr->size))
return False;
if (!prs_uint32("data_ptr", ps, depth, &buf_hdr->data_ptr))
return False;
return True;
}
/*******************************************************************
********************************************************************/
static BOOL smb_io_lsa_data_buf(const char *desc, LSA_DATA_BUF *buf,
prs_struct *ps, int depth, int length, int size)
{
prs_debug(ps, depth, desc, "smb_io_lsa_data_buf");
depth++;
if ( UNMARSHALLING(ps) ) {
if ( !(buf->data = PRS_ALLOC_MEM( ps, uint8, length )) )
return False;
}
if (!prs_uint32("size", ps, depth, &buf->size))
return False;
if (!prs_uint32("offset", ps, depth, &buf->offset))
return False;
if (!prs_uint32("length", ps, depth, &buf->length))
return False;
if(!prs_uint8s(False, "data", ps, depth, buf->data, size))
return False;
return True;
}
/*******************************************************************
********************************************************************/
static BOOL lsa_io_trustdom_query_1(const char *desc, TRUSTED_DOMAIN_INFO_NAME *name,
prs_struct *ps, int depth)
{
if (!smb_io_lsa_string("netbios_name", &name->netbios_name, ps, depth))
return False;
return True;
}
/*******************************************************************
********************************************************************/
static BOOL lsa_io_trustdom_query_3(const char *desc, TRUSTED_DOMAIN_INFO_POSIX_OFFSET *posix,
prs_struct *ps, int depth)
{
if(!prs_uint32("posix_offset", ps, depth, &posix->posix_offset))
return False;
return True;
}
/*******************************************************************
********************************************************************/
static BOOL lsa_io_trustdom_query_4(const char *desc, TRUSTED_DOMAIN_INFO_PASSWORD *password,
prs_struct *ps, int depth)
{
if(!prs_align(ps))
return False;
if(!prs_uint32("ptr_password", ps, depth, &password->ptr_password))
return False;
if(!prs_uint32("ptr_old_password", ps, depth, &password->ptr_old_password))
return False;
if (&password->ptr_password) {
if (!smb_io_lsa_data_buf_hdr("password_hdr", &password->password_hdr, ps, depth))
return False;
if (!smb_io_lsa_data_buf("password", &password->password, ps, depth,
password->password_hdr.length, password->password_hdr.size))
return False;
}
if (&password->ptr_old_password) {
if (!smb_io_lsa_data_buf_hdr("old_password_hdr", &password->old_password_hdr, ps, depth))
return False;
if (!smb_io_lsa_data_buf("old_password", &password->old_password, ps, depth,
password->old_password_hdr.length, password->old_password_hdr.size))
return False;
}
return True;
}
/*******************************************************************
********************************************************************/
static BOOL lsa_io_trustdom_query(const char *desc, prs_struct *ps, int depth, LSA_TRUSTED_DOMAIN_INFO *info)
{
prs_debug(ps, depth, desc, "lsa_io_trustdom_query");
depth++;
if(!prs_uint16("info_class", ps, depth, &info->info_class))
return False;
if(!prs_align(ps))
return False;
switch (info->info_class) {
case 1:
if(!lsa_io_trustdom_query_1("name", &info->name, ps, depth))
return False;
break;
case 3:
if(!lsa_io_trustdom_query_3("posix_offset", &info->posix_offset, ps, depth))
return False;
break;
case 4:
if(!lsa_io_trustdom_query_4("password", &info->password, ps, depth))
return False;
break;
default:
DEBUG(0,("unsupported info-level: %d\n", info->info_class));
return False;
break;
}
return True;
}
/*******************************************************************
Reads or writes an LSA_R_QUERY_TRUSTED_DOMAIN_INFO structure.
********************************************************************/
BOOL lsa_io_r_query_trusted_domain_info(const char *desc,
LSA_R_QUERY_TRUSTED_DOMAIN_INFO *r_q,
prs_struct *ps, int depth)
{
if (r_q == NULL)
return False;
prs_debug(ps, depth, desc, "lsa_io_r_query_trusted_domain_info");
depth++;
if (!prs_pointer("trustdom", ps, depth, (void**)&r_q->info,
sizeof(LSA_TRUSTED_DOMAIN_INFO),
(PRS_POINTER_CAST)lsa_io_trustdom_query) )
return False;
if(!prs_align(ps))
return False;
if(!prs_ntstatus("status", ps, depth, &r_q->status))
return False;
return True;
}

View File

@ -746,6 +746,191 @@ static NTSTATUS cmd_lsa_query_secobj(struct cli_state *cli,
return result;
}
static void display_trust_dom_info_1(TRUSTED_DOMAIN_INFO_NAME *n)
{
printf("NetBIOS Name:\t%s\n", unistr2_static(&n->netbios_name.unistring));
}
static void display_trust_dom_info_3(TRUSTED_DOMAIN_INFO_POSIX_OFFSET *p)
{
printf("Posix Offset:\t%d\n", p->posix_offset);
}
static void display_trust_dom_info_4(TRUSTED_DOMAIN_INFO_PASSWORD *p, const char *password)
{
char *pwd, *pwd_old;
DATA_BLOB data = data_blob(NULL, p->password.length);
DATA_BLOB data_old = data_blob(NULL, p->old_password.length);
memcpy(data.data, p->password.data, p->password.length);
data.length = p->password.length;
memcpy(data_old.data, p->old_password.data, p->old_password.length);
data_old.length = p->old_password.length;
pwd = decrypt_trustdom_secret(password, &data);
pwd_old = decrypt_trustdom_secret(password, &data_old);
printf("Password:\t%s\n", pwd);
printf("Old Password:\t%s\n", pwd_old);
SAFE_FREE(pwd);
SAFE_FREE(pwd_old);
data_blob_free(&data);
data_blob_free(&data_old);
}
static void display_trust_dom_info(LSA_TRUSTED_DOMAIN_INFO *info, uint32 info_class, const char *pass)
{
switch (info_class) {
case 1:
display_trust_dom_info_1(&info->name);
break;
case 3:
display_trust_dom_info_3(&info->posix_offset);
break;
case 4:
display_trust_dom_info_4(&info->password, pass);
break;
default:
printf("unsupported info-class: %d\n", info_class);
break;
}
}
static NTSTATUS cmd_lsa_query_trustdominfobysid(struct cli_state *cli,
TALLOC_CTX *mem_ctx, int argc,
const char **argv)
{
POLICY_HND pol;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
DOM_SID dom_sid;
uint32 access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
LSA_TRUSTED_DOMAIN_INFO *info;
uint32 info_class = 1;
if (argc > 3 || argc < 2) {
printf("Usage: %s [sid] [info_class]\n", argv[0]);
return NT_STATUS_OK;
}
if (!string_to_sid(&dom_sid, argv[1]))
return NT_STATUS_NO_MEMORY;
if (argc == 3)
info_class = atoi(argv[2]);
result = cli_lsa_open_policy2(cli, mem_ctx, True, access_mask, &pol);
if (!NT_STATUS_IS_OK(result))
goto done;
result = cli_lsa_query_trusted_domain_info_by_sid(cli, mem_ctx, &pol,
info_class, &dom_sid, &info);
if (!NT_STATUS_IS_OK(result))
goto done;
display_trust_dom_info(info, info_class, cli->pwd.password);
done:
if (&pol)
cli_lsa_close(cli, mem_ctx, &pol);
return result;
}
static NTSTATUS cmd_lsa_query_trustdominfobyname(struct cli_state *cli,
TALLOC_CTX *mem_ctx, int argc,
const char **argv)
{
POLICY_HND pol;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
uint32 access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
LSA_TRUSTED_DOMAIN_INFO *info;
uint32 info_class = 1;
if (argc > 3 || argc < 2) {
printf("Usage: %s [name] [info_class]\n", argv[0]);
return NT_STATUS_OK;
}
if (argc == 3)
info_class = atoi(argv[2]);
result = cli_lsa_open_policy2(cli, mem_ctx, True, access_mask, &pol);
if (!NT_STATUS_IS_OK(result))
goto done;
result = cli_lsa_query_trusted_domain_info_by_name(cli, mem_ctx, &pol,
info_class, argv[1], &info);
if (!NT_STATUS_IS_OK(result))
goto done;
display_trust_dom_info(info, info_class, cli->pwd.password);
done:
if (&pol)
cli_lsa_close(cli, mem_ctx, &pol);
return result;
}
static NTSTATUS cmd_lsa_query_trustdominfo(struct cli_state *cli,
TALLOC_CTX *mem_ctx, int argc,
const char **argv)
{
POLICY_HND pol, trustdom_pol;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
uint32 access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED;
LSA_TRUSTED_DOMAIN_INFO *info;
DOM_SID dom_sid;
uint32 info_class = 1;
if (argc > 3 || argc < 2) {
printf("Usage: %s [sid] [info_class]\n", argv[0]);
return NT_STATUS_OK;
}
if (!string_to_sid(&dom_sid, argv[1]))
return NT_STATUS_NO_MEMORY;
if (argc == 3)
info_class = atoi(argv[2]);
result = cli_lsa_open_policy2(cli, mem_ctx, True, access_mask, &pol);
if (!NT_STATUS_IS_OK(result))
goto done;
result = cli_lsa_open_trusted_domain(cli, mem_ctx, &pol,
&dom_sid, access_mask, &trustdom_pol);
if (!NT_STATUS_IS_OK(result))
goto done;
result = cli_lsa_query_trusted_domain_info(cli, mem_ctx, &trustdom_pol,
info_class, &dom_sid, &info);
if (!NT_STATUS_IS_OK(result))
goto done;
display_trust_dom_info(info, info_class, cli->pwd.password);
done:
if (&pol)
cli_lsa_close(cli, mem_ctx, &pol);
return result;
}
/* List of commands exported by this module */
@ -771,6 +956,9 @@ struct cmd_set lsarpc_commands[] = {
{ "lsaremoveacctrights", RPC_RTYPE_NTSTATUS, cmd_lsa_remove_acct_rights, NULL, PI_LSARPC, "Remove rights from an account", "" },
{ "lsalookupprivvalue", RPC_RTYPE_NTSTATUS, cmd_lsa_lookup_priv_value, NULL, PI_LSARPC, "Get a privilege value given its name", "" },
{ "lsaquerysecobj", RPC_RTYPE_NTSTATUS, cmd_lsa_query_secobj, NULL, PI_LSARPC, "Query LSA security object", "" },
{ "lsaquerytrustdominfo",RPC_RTYPE_NTSTATUS, cmd_lsa_query_trustdominfo, NULL, PI_LSARPC, "Query LSA trusted domains info (given a SID)", "" },
{ "lsaquerytrustdominfobyname",RPC_RTYPE_NTSTATUS, cmd_lsa_query_trustdominfobyname, NULL, PI_LSARPC, "Query LSA trusted domains info (given a name), only works for Windows > 2k", "" },
{ "lsaquerytrustdominfobysid",RPC_RTYPE_NTSTATUS, cmd_lsa_query_trustdominfobysid, NULL, PI_LSARPC, "Query LSA trusted domains info (given a SID)", "" },
{ NULL }
};

View File

@ -204,10 +204,10 @@ static NTSTATUS cmd_listcommands(struct cli_state *cli, TALLOC_CTX *mem_ctx,
i = 0;
tmp_set++;
while(tmp_set->name) {
printf("%20s", tmp_set->name);
printf("%30s", tmp_set->name);
tmp_set++;
i++;
if (i%4 == 0)
if (i%3 == 0)
printf("\n");
}

View File

@ -4795,6 +4795,7 @@ static int rpc_trustdom_usage(int argc, const char **argv)
d_printf(" net rpc trustdom establish \t establish relationship to trusted domain\n");
d_printf(" net rpc trustdom revoke \t abandon relationship to trusted domain\n");
d_printf(" net rpc trustdom list \t show current interdomain trust relationships\n");
d_printf(" net rpc trustdom vampire \t vampire interdomain trust relationships from remote server\n");
return -1;
}
@ -4810,6 +4811,201 @@ static NTSTATUS rpc_query_domain_sid(const DOM_SID *domain_sid,
return NT_STATUS_OK;
}
static void print_trusted_domain(DOM_SID *dom_sid, const char *trusted_dom_name)
{
fstring ascii_sid, padding;
int pad_len, col_len = 20;
/* convert sid into ascii string */
sid_to_string(ascii_sid, dom_sid);
/* calculate padding space for d_printf to look nicer */
pad_len = col_len - strlen(trusted_dom_name);
padding[pad_len] = 0;
do padding[--pad_len] = ' '; while (pad_len);
d_printf("%s%s%s\n", trusted_dom_name, padding, ascii_sid);
}
static NTSTATUS vampire_trusted_domain(struct cli_state *cli,
TALLOC_CTX *mem_ctx,
POLICY_HND *pol,
DOM_SID dom_sid,
const char *trusted_dom_name)
{
NTSTATUS nt_status;
LSA_TRUSTED_DOMAIN_INFO *info;
char *cleartextpwd;
DATA_BLOB data;
smb_ucs2_t *uni_dom_name;
nt_status = cli_lsa_query_trusted_domain_info_by_sid(cli, mem_ctx, pol, 4, &dom_sid, &info);
if (NT_STATUS_IS_ERR(nt_status)) {
DEBUG(0,("Could not query trusted domain info. Error was %s\n",
nt_errstr(nt_status)));
goto done;
}
data = data_blob(NULL, info->password.password.length);
memcpy(data.data, info->password.password.data, info->password.password.length);
data.length = info->password.password.length;
cleartextpwd = decrypt_trustdom_secret(cli->pwd.password, &data);
if (cleartextpwd == NULL) {
DEBUG(0,("retrieved NULL password\n"));
nt_status = NT_STATUS_UNSUCCESSFUL;
goto done;
}
if (push_ucs2_talloc(mem_ctx, &uni_dom_name, trusted_dom_name) < 0) {
DEBUG(0, ("Could not convert domain name %s to unicode\n",
trusted_dom_name));
nt_status = NT_STATUS_UNSUCCESSFUL;
goto done;
}
if (!secrets_store_trusted_domain_password(trusted_dom_name,
uni_dom_name,
strlen_w(uni_dom_name)+1,
cleartextpwd,
dom_sid)) {
DEBUG(0, ("Storing password for trusted domain failed.\n"));
nt_status = NT_STATUS_UNSUCCESSFUL;
goto done;
}
DEBUG(100,("sucessfully vampired trusted domain [%s], sid: [%s], password: [%s]\n",
trusted_dom_name, sid_string_static(&dom_sid), cleartextpwd));
done:
SAFE_FREE(cleartextpwd);
data_blob_free(&data);
return nt_status;
}
static int rpc_trustdom_vampire(int argc, const char **argv)
{
/* common variables */
TALLOC_CTX* mem_ctx;
struct cli_state *cli;
NTSTATUS nt_status;
const char *domain_name = NULL;
DOM_SID *queried_dom_sid;
POLICY_HND connect_hnd;
/* trusted domains listing variables */
unsigned int num_domains, enum_ctx = 0;
int i;
DOM_SID *domain_sids;
char **trusted_dom_names;
fstring pdc_name;
char *dummy;
/*
* Listing trusted domains (stored in secrets.tdb, if local)
*/
mem_ctx = talloc_init("trust relationships vampire");
/*
* set domain and pdc name to local samba server (default)
* or to remote one given in command line
*/
if (StrCaseCmp(opt_workgroup, lp_workgroup())) {
domain_name = opt_workgroup;
opt_target_workgroup = opt_workgroup;
} else {
fstrcpy(pdc_name, global_myname());
domain_name = talloc_strdup(mem_ctx, lp_workgroup());
opt_target_workgroup = domain_name;
};
/* open \PIPE\lsarpc and open policy handle */
if (!(cli = net_make_ipc_connection(NET_FLAGS_PDC))) {
DEBUG(0, ("Couldn't connect to domain controller\n"));
return -1;
};
if (!cli_nt_session_open(cli, PI_LSARPC)) {
DEBUG(0, ("Could not initialise lsa pipe\n"));
return -1;
};
nt_status = cli_lsa_open_policy2(cli, mem_ctx, False, SEC_RIGHTS_QUERY_VALUE,
&connect_hnd);
if (NT_STATUS_IS_ERR(nt_status)) {
DEBUG(0, ("Couldn't open policy handle. Error was %s\n",
nt_errstr(nt_status)));
return -1;
};
/* query info level 5 to obtain sid of a domain being queried */
nt_status = cli_lsa_query_info_policy(
cli, mem_ctx, &connect_hnd, 5 /* info level */,
&dummy, &queried_dom_sid);
if (NT_STATUS_IS_ERR(nt_status)) {
DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
nt_errstr(nt_status)));
return -1;
}
/*
* Keep calling LsaEnumTrustdom over opened pipe until
* the end of enumeration is reached
*/
d_printf("Vampire trusted domains:\n\n");
do {
nt_status = cli_lsa_enum_trust_dom(cli, mem_ctx, &connect_hnd, &enum_ctx,
&num_domains,
&trusted_dom_names, &domain_sids);
if (NT_STATUS_IS_ERR(nt_status)) {
DEBUG(0, ("Couldn't enumerate trusted domains. Error was %s\n",
nt_errstr(nt_status)));
return -1;
};
for (i = 0; i < num_domains; i++) {
print_trusted_domain(&(domain_sids[i]), trusted_dom_names[i]);
nt_status = vampire_trusted_domain(cli, mem_ctx, &connect_hnd,
domain_sids[i], trusted_dom_names[i]);
if (!NT_STATUS_IS_OK(nt_status))
return -1;
};
/*
* in case of no trusted domains say something rather
* than just display blank line
*/
if (!num_domains) d_printf("none\n");
} while (NT_STATUS_EQUAL(nt_status, STATUS_MORE_ENTRIES));
/* close this connection before doing next one */
nt_status = cli_lsa_close(cli, mem_ctx, &connect_hnd);
if (NT_STATUS_IS_ERR(nt_status)) {
DEBUG(0, ("Couldn't properly close lsa policy handle. Error was %s\n",
nt_errstr(nt_status)));
return -1;
};
/* close lsarpc pipe and connection to IPC$ */
cli_nt_session_close(cli);
cli_shutdown(cli);
talloc_destroy(mem_ctx);
return 0;
}
static int rpc_trustdom_list(int argc, const char **argv)
{
@ -4819,7 +5015,7 @@ static int rpc_trustdom_list(int argc, const char **argv)
NTSTATUS nt_status;
const char *domain_name = NULL;
DOM_SID *queried_dom_sid;
fstring ascii_sid, padding;
fstring padding;
int ascii_dom_name_len;
POLICY_HND connect_hnd;
@ -4905,15 +5101,7 @@ static int rpc_trustdom_list(int argc, const char **argv)
};
for (i = 0; i < num_domains; i++) {
/* convert sid into ascii string */
sid_to_string(ascii_sid, &(domain_sids[i]));
/* calculate padding space for d_printf to look nicer */
pad_len = col_len - strlen(trusted_dom_names[i]);
padding[pad_len] = 0;
do padding[--pad_len] = ' '; while (pad_len);
d_printf("%s%s%s\n", trusted_dom_names[i], padding, ascii_sid);
print_trusted_domain(&(domain_sids[i]), trusted_dom_names[i]);
};
/*
@ -5065,6 +5253,7 @@ static int rpc_trustdom(int argc, const char **argv)
{"revoke", rpc_trustdom_revoke},
{"help", rpc_trustdom_usage},
{"list", rpc_trustdom_list},
{"vampire", rpc_trustdom_vampire},
{NULL, NULL}
};