summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Chapman <matty@samba.org>1999-04-08 05:36:15 +0000
committerMatthew Chapman <matty@samba.org>1999-04-08 05:36:15 +0000
commit373ea639e03e72bef8242133abbf678cf90ed0d9 (patch)
treec6fb6d1918c77c49f039ba0953dc4066abbb2d9c
parent53f0cd990c3d26e73b42266be35516d6db9621e0 (diff)
downloadsamba-373ea639e03e72bef8242133abbf678cf90ed0d9.tar.gz
samba-373ea639e03e72bef8242133abbf678cf90ed0d9.tar.bz2
samba-373ea639e03e72bef8242133abbf678cf90ed0d9.zip
Mainly BDC-related changes.
* Added SEC_CHAN_BDC * Propagate sec_chan into the various functions which change trust account passwords, so they can be used for domain control and inter-domain trusts. * Fix for endianness problem reported by Edan Idzerda <edan@mtu.edu>. A BUFFER2 is really a "unibuf" in my terminology and we should treat it as such. * Added some more common NT structures (BIGINT, BUFHDR2, BUFFER4). * Added NET_SAM_SYNC (-> NetDatabaseSync2) RPC for account replication. Still experimental and incomplete, with a few too many NULL security descriptors lying around (must go look at Jeremy's SD code). Haven't worked out password encryption yet either. However, the XXX_INFO structures I've added to rpc_netlogon.h are quite nice as they give some insight into how these objects are stored in the SAM. (This used to be commit 7b830350eb54dc9d357c115e12ddf9a0633527ac)
-rw-r--r--source3/rpc_client/cli_login.c5
-rw-r--r--source3/rpc_client/cli_netlogon.c70
-rw-r--r--source3/rpc_client/cli_reg.c2
-rw-r--r--source3/rpc_parse/parse_misc.c99
-rw-r--r--source3/rpc_parse/parse_net.c484
-rw-r--r--source3/rpc_parse/parse_prs.c2
-rw-r--r--source3/rpc_parse/parse_reg.c9
-rw-r--r--source3/rpcclient/cmd_netlogon.c30
-rw-r--r--source3/rpcclient/display.c2
-rw-r--r--source3/rpcclient/rpcclient.c1
10 files changed, 648 insertions, 56 deletions
diff --git a/source3/rpc_client/cli_login.c b/source3/rpc_client/cli_login.c
index 3769f44e18..858327a1b2 100644
--- a/source3/rpc_client/cli_login.c
+++ b/source3/rpc_client/cli_login.c
@@ -80,7 +80,8 @@ BOOL cli_nt_setup_creds(struct cli_state *cli, uint16 fnum,
Set machine password.
****************************************************************************/
-BOOL cli_nt_srv_pwset(struct cli_state *cli, uint16 fnum, unsigned char *new_hashof_trust_pwd)
+BOOL cli_nt_srv_pwset(struct cli_state *cli, uint16 fnum,
+ unsigned char *new_hashof_trust_pwd, uint16 sec_chan)
{
unsigned char processed_new_pwd[16];
@@ -94,7 +95,7 @@ BOOL cli_nt_srv_pwset(struct cli_state *cli, uint16 fnum, unsigned char *new_has
cred_hash3( processed_new_pwd, new_hashof_trust_pwd, cli->sess_key, 1);
/* send client srv_pwset challenge */
- return cli_net_srv_pwset(cli, fnum, processed_new_pwd);
+ return cli_net_srv_pwset(cli, fnum, processed_new_pwd, sec_chan);
}
/****************************************************************************
diff --git a/source3/rpc_client/cli_netlogon.c b/source3/rpc_client/cli_netlogon.c
index ff9fc3c5ed..9bd7d695d2 100644
--- a/source3/rpc_client/cli_netlogon.c
+++ b/source3/rpc_client/cli_netlogon.c
@@ -257,14 +257,14 @@ BOOL cli_net_req_chal(struct cli_state *cli, uint16 nt_pipe_fnum, DOM_CHAL *clnt
LSA Server Password Set.
****************************************************************************/
-BOOL cli_net_srv_pwset(struct cli_state *cli, uint16 nt_pipe_fnum, uint8 hashed_mach_pwd[16])
+BOOL cli_net_srv_pwset(struct cli_state *cli, uint16 nt_pipe_fnum,
+ uint8 hashed_mach_pwd[16], uint16 sec_chan_type)
{
prs_struct rbuf;
prs_struct buf;
DOM_CRED new_clnt_cred;
NET_Q_SRV_PWSET q_s;
BOOL ok = False;
- uint16 sec_chan_type = 2;
gen_next_creds( cli, &new_clnt_cred);
@@ -473,13 +473,68 @@ password ?).\n", cli->desthost ));
return ok;
}
+/***************************************************************************
+Synchronise SAM Database (requires SEC_CHAN_BDC).
+****************************************************************************/
+BOOL cli_net_sam_sync(struct cli_state *cli, uint16 nt_pipe_fnum, uint32 database_id)
+{
+ NET_Q_SAM_SYNC q_s;
+ prs_struct rbuf;
+ prs_struct buf;
+ DOM_CRED new_clnt_cred;
+ BOOL ok = False;
+
+ gen_next_creds(cli, &new_clnt_cred);
+
+ prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
+ prs_init(&rbuf, 0, 4, SAFETY_MARGIN, True );
+
+ /* create and send a MSRPC command with api NET_SAM_SYNC */
+
+ make_q_sam_sync(&q_s, cli->srv_name_slash, global_myname,
+ &new_clnt_cred, database_id);
+
+ /* turn parameters into data stream */
+ net_io_q_sam_sync("", &q_s, &buf, 0);
+
+ /* send the data on \PIPE\ */
+ if (rpc_api_pipe_req(cli, nt_pipe_fnum, NET_SAM_SYNC, &buf, &rbuf))
+ {
+ NET_R_SAM_SYNC r_s;
+
+ net_io_r_sam_sync("", &r_s, &rbuf, 0);
+ ok = (rbuf.offset != 0);
+
+ if (ok && r_s.status != 0)
+ {
+ /* report error code */
+ DEBUG(0,("cli_net_sam_sync: %s\n", get_nt_error_msg(r_s.status)));
+ cli->nt_error = r_s.status;
+ ok = False;
+ }
+
+ /* Update the credentials. */
+ if (ok && !clnt_deal_with_creds(cli->sess_key, &(cli->clnt_cred), &(r_s.srv_creds)))
+ {
+ DEBUG(0,("cli_net_sam_sync: server %s replied with bad credential (bad machine password ?).\n", cli->desthost));
+ ok = False;
+ }
+ }
+
+ prs_mem_free(&rbuf);
+ prs_mem_free(&buf );
+
+ return ok;
+}
+
/*********************************************************
Change the domain password on the PDC.
**********************************************************/
static BOOL modify_trust_password( char *domain, char *remote_machine,
unsigned char orig_trust_passwd_hash[16],
- unsigned char new_trust_passwd_hash[16])
+ unsigned char new_trust_passwd_hash[16],
+ uint16 sec_chan)
{
uint16 nt_pipe_fnum;
struct cli_state cli;
@@ -575,7 +630,7 @@ machine %s. Error was : %s.\n", remote_machine, cli_errstr(&cli)));
}
if(cli_nt_setup_creds(&cli, nt_pipe_fnum,
- cli.mach_acct, orig_trust_passwd_hash, SEC_CHAN_WKSTA) == False) {
+ cli.mach_acct, orig_trust_passwd_hash, sec_chan) == False) {
DEBUG(0,("modify_trust_password: unable to setup the PDC credentials to machine \
%s. Error was : %s.\n", remote_machine, cli_errstr(&cli)));
cli_nt_session_close(&cli, nt_pipe_fnum);
@@ -584,7 +639,7 @@ machine %s. Error was : %s.\n", remote_machine, cli_errstr(&cli)));
return False;
}
- if( cli_nt_srv_pwset( &cli, nt_pipe_fnum, new_trust_passwd_hash ) == False) {
+ if( cli_nt_srv_pwset( &cli, nt_pipe_fnum, new_trust_passwd_hash, sec_chan ) == False) {
DEBUG(0,("modify_trust_password: unable to change password for machine %s in domain \
%s to Domain controller %s. Error was %s.\n", global_myname, domain, remote_machine,
cli_errstr(&cli)));
@@ -607,7 +662,8 @@ machine %s. Error was : %s.\n", remote_machine, cli_errstr(&cli)));
update.
************************************************************************/
-BOOL change_trust_account_password( char *domain, char *remote_machine_list)
+BOOL change_trust_account_password(char *domain, char *remote_machine_list,
+ uint16 sec_chan)
{
fstring remote_machine;
unsigned char old_trust_passwd_hash[16];
@@ -631,7 +687,7 @@ account password for domain %s.\n", domain));
LIST_SEP, sizeof(remote_machine))) {
strupper(remote_machine);
if(modify_trust_password( domain, remote_machine,
- old_trust_passwd_hash, new_trust_passwd_hash)) {
+ old_trust_passwd_hash, new_trust_passwd_hash, sec_chan)) {
DEBUG(0,("%s : change_trust_account_password: Changed password for \
domain %s.\n", timestring(), domain));
/*
diff --git a/source3/rpc_client/cli_reg.c b/source3/rpc_client/cli_reg.c
index 04b1fdc650..c467d8abaa 100644
--- a/source3/rpc_client/cli_reg.c
+++ b/source3/rpc_client/cli_reg.c
@@ -425,7 +425,7 @@ BOOL do_reg_query_info(struct cli_state *cli, uint16 fnum, POLICY_HND *hnd,
if (p)
{
valid_query = True;
- unistr_to_ascii(type, r_o.uni_type.buffer,
+ unibuf_to_ascii(type, r_o.uni_type.buffer,
MIN(r_o.uni_type.buf_len, sizeof(fstring)-1));
(*unk_0) = r_o.unknown_0;
(*unk_1) = r_o.unknown_1;
diff --git a/source3/rpc_parse/parse_misc.c b/source3/rpc_parse/parse_misc.c
index 64cbdef716..51587e6d7a 100644
--- a/source3/rpc_parse/parse_misc.c
+++ b/source3/rpc_parse/parse_misc.c
@@ -28,6 +28,21 @@
extern int DEBUGLEVEL;
+/*******************************************************************
+reads or writes a BIGINT structure.
+********************************************************************/
+void smb_io_bigint(char *desc, BIGINT *bigint, prs_struct *ps, int depth)
+{
+ if (bigint == NULL) return;
+
+ prs_debug(ps, depth, desc, "smb_io_bigint");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("low ", ps, depth, &(bigint->low ));
+ prs_uint32("high", ps, depth, &(bigint->high));
+}
/*******************************************************************
reads or writes a UTIME type.
@@ -311,6 +326,7 @@ void smb_io_hdrbuf_post(char *desc, BUFHDR *hdr, prs_struct *ps, int depth,
ps->offset = old_offset;
}
}
+
/*******************************************************************
reads or writes a BUFHDR structure.
********************************************************************/
@@ -332,6 +348,32 @@ void smb_io_hdrbuf(char *desc, BUFHDR *hdr, prs_struct *ps, int depth)
}
/*******************************************************************
+creates a BUFHDR2 structure.
+********************************************************************/
+void make_bufhdr2(BUFHDR2 *hdr, uint32 info_level, uint32 length, uint32 buffer)
+{
+ hdr->info_level = info_level;
+ hdr->length = length;
+ hdr->buffer = buffer;
+}
+
+/*******************************************************************
+reads or writes a BUFHDR2 structure.
+********************************************************************/
+void smb_io_bufhdr2(char *desc, BUFHDR2 *hdr, prs_struct *ps, int depth)
+{
+ if (hdr == NULL) return;
+
+ prs_debug(ps, depth, desc, "smb_io_bufhdr2");
+ depth++;
+
+ prs_align(ps);
+ prs_uint32("info_level", ps, depth, &(hdr->info_level));
+ prs_uint32("length ", ps, depth, &(hdr->length ));
+ prs_uint32("buffer ", ps, depth, &(hdr->buffer ));
+}
+
+/*******************************************************************
creates a UNIHDR2 structure.
********************************************************************/
void make_uni_hdr2(UNIHDR2 *hdr, int len)
@@ -456,6 +498,27 @@ void smb_io_buffer3(char *desc, BUFFER3 *buf3, prs_struct *ps, int depth)
}
/*******************************************************************
+reads or writes a BUFFER4 structure.
+********************************************************************/
+void smb_io_buffer4(char *desc, BUFFER4 *buf4, uint32 buffer, prs_struct *ps, int depth)
+{
+ if ((buf4 == NULL) || (buffer == 0)) return;
+
+ prs_debug(ps, depth, desc, "smb_io_buffer4");
+ depth++;
+
+ prs_align(ps);
+ prs_uint32("buf_len", ps, depth, &(buf4->buf_len));
+
+ if (buf4->buf_len > MAX_BUFFERLEN)
+ {
+ buf4->buf_len = MAX_BUFFERLEN;
+ }
+
+ prs_uint8s(True, "buffer", ps, depth, buf4->buffer, buf4->buf_len);
+}
+
+/*******************************************************************
creates a BUFFER2 structure.
********************************************************************/
void make_buffer2(BUFFER2 *str, const char *buf, int len)
@@ -463,12 +526,11 @@ void make_buffer2(BUFFER2 *str, const char *buf, int len)
ZERO_STRUCTP(str);
/* set up string lengths. */
- str->buf_max_len = len;
+ str->buf_max_len = str->buf_len = len * 2;
str->undoc = 0;
- str->buf_len = len;
- /* store the string (wide chars) */
- ascii_to_unistr(str->buffer, buf, len);
+ /* store the string */
+ ascii_to_unibuf(str->buffer, buf, len);
}
/*******************************************************************
@@ -910,35 +972,6 @@ void smb_io_clnt_info(char *desc, DOM_CLNT_INFO *clnt, prs_struct *ps, int dept
}
/*******************************************************************
-makes a DOM_LOGON_ID structure.
-********************************************************************/
-void make_logon_id(DOM_LOGON_ID *log, uint32 log_id_low, uint32 log_id_high)
-{
- if (log == NULL) return;
-
- DEBUG(5,("make_logon_id: %d\n", __LINE__));
-
- log->low = log_id_low;
- log->high = log_id_high;
-}
-
-/*******************************************************************
-reads or writes a DOM_LOGON_ID structure.
-********************************************************************/
-void smb_io_logon_id(char *desc, DOM_LOGON_ID *log, prs_struct *ps, int depth)
-{
- if (log == NULL) return;
-
- prs_debug(ps, depth, desc, "smb_io_logon_id");
- depth++;
-
- prs_align(ps);
-
- prs_uint32("low ", ps, depth, &(log->low ));
- prs_uint32("high", ps, depth, &(log->high));
-}
-
-/*******************************************************************
makes an OWF_INFO structure.
********************************************************************/
void make_owf_info(OWF_INFO *hash, uint8 data[16])
diff --git a/source3/rpc_parse/parse_net.c b/source3/rpc_parse/parse_net.c
index 69d2b3bf57..083816771f 100644
--- a/source3/rpc_parse/parse_net.c
+++ b/source3/rpc_parse/parse_net.c
@@ -564,7 +564,8 @@ void make_id_info1(NET_ID_INFO_1 *id, char *domain_name,
make_uni_hdr(&(id->hdr_domain_name), len_domain_name);
id->param_ctrl = param_ctrl;
- make_logon_id(&(id->logon_id), log_id_low, log_id_high);
+ id->logon_id.low = log_id_low;
+ id->logon_id.high = log_id_high;
make_uni_hdr(&(id->hdr_user_name ), len_user_name );
make_uni_hdr(&(id->hdr_wksta_name ), len_wksta_name );
@@ -627,7 +628,7 @@ static void net_io_id_info1(char *desc, NET_ID_INFO_1 *id, prs_struct *ps, int
smb_io_unihdr("unihdr", &(id->hdr_domain_name), ps, depth);
prs_uint32("param_ctrl", ps, depth, &(id->param_ctrl));
- smb_io_logon_id("", &(id->logon_id), ps, depth);
+ smb_io_bigint("", &(id->logon_id), ps, depth);
smb_io_unihdr("unihdr", &(id->hdr_user_name ), ps, depth);
smb_io_unihdr("unihdr", &(id->hdr_wksta_name ), ps, depth);
@@ -680,7 +681,8 @@ void make_id_info2(NET_ID_INFO_2 *id, char *domain_name,
make_uni_hdr(&(id->hdr_domain_name), len_domain_name);
id->param_ctrl = param_ctrl;
- make_logon_id(&(id->logon_id), log_id_low, log_id_high);
+ id->logon_id.low = log_id_low;
+ id->logon_id.high = log_id_high;
make_uni_hdr(&(id->hdr_user_name ), len_user_name );
make_uni_hdr(&(id->hdr_wksta_name ), len_wksta_name );
@@ -729,7 +731,7 @@ static void net_io_id_info2(char *desc, NET_ID_INFO_2 *id, prs_struct *ps, int
smb_io_unihdr("unihdr", &(id->hdr_domain_name), ps, depth);
prs_uint32("param_ctrl", ps, depth, &(id->param_ctrl));
- smb_io_logon_id("", &(id->logon_id), ps, depth);
+ smb_io_bigint("", &(id->logon_id), ps, depth);
smb_io_unihdr("unihdr", &(id->hdr_user_name ), ps, depth);
smb_io_unihdr("unihdr", &(id->hdr_wksta_name ), ps, depth);
@@ -1117,4 +1119,478 @@ void net_io_r_sam_logoff(char *desc, NET_R_SAM_LOGOFF *r_l, prs_struct *ps, int
prs_uint32("status ", ps, depth, &(r_l->status));
}
+/*******************************************************************
+makes a NET_Q_SAM_SYNC structure.
+********************************************************************/
+void make_q_sam_sync(NET_Q_SAM_SYNC *q_s, char *srv_name, char *cli_name,
+ DOM_CRED *cli_creds, uint32 database_id)
+{
+ if (q_s == NULL) return;
+
+ DEBUG(5,("make_q_sam_sync\n"));
+
+ make_unistr2(&(q_s->uni_srv_name), srv_name, strlen(srv_name)+1);
+ make_unistr2(&(q_s->uni_cli_name), cli_name, strlen(cli_name)+1);
+
+ memcpy(&(q_s->cli_creds), cli_creds, sizeof(q_s->cli_creds));
+ memset(&(q_s->ret_creds), 0, sizeof(q_s->ret_creds));
+
+ q_s->database_id = database_id;
+ q_s->restart_state = 0;
+ q_s->sync_context = 0;
+ q_s->max_size = 0xffff;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void net_io_q_sam_sync(char *desc, NET_Q_SAM_SYNC *q_s, prs_struct *ps, int depth)
+{
+ if (q_s == NULL) return;
+
+ prs_debug(ps, depth, desc, "net_io_q_sam_sync");
+ depth++;
+
+ smb_io_unistr2("", &(q_s->uni_srv_name), True, ps, depth);
+ smb_io_unistr2("", &(q_s->uni_cli_name), True, ps, depth);
+
+ smb_io_cred("", &(q_s->cli_creds), ps, depth);
+ smb_io_cred("", &(q_s->ret_creds), ps, depth);
+
+ prs_uint32("database_id ", ps, depth, &(q_s->database_id ));
+ prs_uint32("restart_state", ps, depth, &(q_s->restart_state));
+ prs_uint32("sync_context ", ps, depth, &(q_s->sync_context ));
+
+ prs_uint32("max_size", ps, depth, &(q_s->max_size));
+}
+
+/*******************************************************************
+makes a SAM_DELTA_HDR structure.
+********************************************************************/
+void make_sam_delta_hdr(SAM_DELTA_HDR *delta, uint16 type, uint32 rid)
+{
+ if (delta == NULL) return;
+
+ DEBUG(5,("make_sam_delta_hdr\n"));
+
+ delta->type2 = delta->type = type;
+ delta->target_rid = rid;
+
+ delta->type3 = type;
+ delta->ptr_delta = 1;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+static void net_io_sam_delta_hdr(char *desc, SAM_DELTA_HDR *delta, prs_struct *ps, int depth)
+{
+ if (delta == NULL) return;
+
+ prs_debug(ps, depth, desc, "net_io_sam_delta_hdr");
+ depth++;
+
+ prs_uint16("type", ps, depth, &(delta->type ));
+ prs_uint16("type2", ps, depth, &(delta->type2 ));
+ prs_uint32("target_rid", ps, depth, &(delta->target_rid));
+
+ prs_uint32("type3", ps, depth, &(delta->type3 ));
+ prs_uint32("ptr_delta", ps, depth, &(delta->ptr_delta ));
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+static void net_io_sam_domain_info(char *desc, SAM_DOMAIN_INFO *info, prs_struct *ps, int depth)
+{
+ if (info == NULL) return;
+
+ prs_debug(ps, depth, desc, "net_io_sam_domain_info");
+ depth++;
+
+ smb_io_unihdr("hdr_dom_name" , &(info->hdr_dom_name) , ps, depth);
+ smb_io_unihdr("hdr_oem_info" , &(info->hdr_oem_info) , ps, depth);
+
+ smb_io_bigint("force_logoff" , &(info->force_logoff) , ps, depth);
+ prs_uint16("min_pwd_len" , ps, depth, &(info->min_pwd_len ));
+ prs_uint16("pwd_history_len" , ps, depth, &(info->pwd_history_len));
+ smb_io_bigint("max_pwd_age" , &(info->max_pwd_age) , ps, depth);
+ smb_io_bigint("min_pwd_age" , &(info->min_pwd_age) , ps, depth);
+ smb_io_bigint("dom_mod_count", &(info->dom_mod_count), ps, depth);
+ smb_io_time("creation_time" , &(info->creation_time), ps, depth);
+
+ smb_io_bufhdr2("hdr_sec_desc", &(info->hdr_sec_desc) , ps, depth);
+ smb_io_unihdr ("hdr_unknown" , &(info->hdr_unknown) , ps, depth);
+
+ smb_io_unistr2("uni_dom_name", &(info->uni_dom_name),
+ info->hdr_dom_name.buffer, ps, depth);
+ smb_io_unistr2("buf_oem_info", &(info->buf_oem_info),
+ info->hdr_oem_info.buffer, ps, depth);
+
+ smb_io_buffer4("buf_sec_desc", &(info->buf_sec_desc),
+ info->hdr_sec_desc.buffer, ps, depth);
+ smb_io_unistr2("buf_unknown" , &(info->buf_unknown ),
+ info->hdr_unknown .buffer, ps, depth);
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+static void net_io_sam_group_info(char *desc, SAM_GROUP_INFO *info, prs_struct *ps, int depth)
+{
+ if (info == NULL) return;
+
+ prs_debug(ps, depth, desc, "net_io_sam_group_info");
+ depth++;
+
+ smb_io_unihdr ("hdr_grp_name", &(info->hdr_grp_name), ps, depth);
+ smb_io_gid ("gid", &(info->gid), ps, depth);
+ smb_io_unihdr ("hdr_grp_desc", &(info->hdr_grp_desc), ps, depth);
+ smb_io_bufhdr2("hdr_sec_desc", &(info->hdr_sec_desc), ps, depth);
+ ps->offset += 48;
+
+ smb_io_unistr2("uni_grp_name", &(info->uni_grp_name),
+ info->hdr_grp_name.buffer, ps, depth);
+ smb_io_unistr2("uni_grp_desc", &(info->uni_grp_desc),
+ info->hdr_grp_name.buffer, ps, depth);
+ smb_io_buffer4("buf_sec_desc", &(info->buf_sec_desc),
+ info->hdr_sec_desc.buffer, ps, depth);
+}
+
+/*******************************************************************
+makes a SAM_ACCOUNT_INFO structure.
+********************************************************************/
+void make_sam_account_info(SAM_ACCOUNT_INFO *info, char *user_name,
+ char *full_name, uint32 user_rid, uint32 group_rid,
+ char *home_dir, char *dir_drive, char *logon_script,
+ char *acct_desc, uint32 acb_info, char *profile)
+{
+ int len_user_name = strlen(user_name);
+ int len_full_name = strlen(full_name);
+ int len_home_dir = strlen(home_dir);
+ int len_dir_drive = strlen(dir_drive);
+ int len_logon_script = strlen(logon_script);
+ int len_acct_desc = strlen(acct_desc);
+ int len_profile = strlen(profile);
+
+ DEBUG(5,("make_sam_account_info\n"));
+
+ make_uni_hdr(&(info->hdr_acct_name ), len_user_name );
+ make_uni_hdr(&(info->hdr_full_name ), len_full_name );
+ make_uni_hdr(&(info->hdr_home_dir ), len_home_dir );
+ make_uni_hdr(&(info->hdr_dir_drive ), len_dir_drive );
+ make_uni_hdr(&(info->hdr_logon_script), len_logon_script);
+ make_uni_hdr(&(info->hdr_acct_desc ), len_acct_desc );
+ make_uni_hdr(&(info->hdr_profile ), len_profile );
+
+ /* not present */
+ make_uni_hdr(&(info->hdr_comment), 0);
+ make_bufhdr2(&(info->hdr_pwd_info), 0, 0, 0);
+ make_bufhdr2(&(info->hdr_sec_desc), 0, 0, 0);
+
+ info->user_rid = user_rid;
+ info->group_rid = group_rid;
+
+ init_nt_time(&(info->time_1));
+ init_nt_time(&(info->time_2));
+ init_nt_time(&(info->time_3));
+ init_nt_time(&(info->time_4));
+ init_nt_time(&(info->time_5));
+
+ info->logon_divs = 0xA8;
+ info->ptr_logon_hrs = 0; /* Don't care right now */
+
+ info->acb_info = acb_info;
+ info->unknown4 = 0x4EC;
+ info->unknown5 = 0;
+
+ make_unistr2(&(info->uni_acct_name), user_name, len_user_name+1);
+ make_unistr2(&(info->uni_full_name), full_name, len_full_name+1);
+ make_unistr2(&(info->uni_home_dir ), home_dir , len_home_dir +1);
+ make_unistr2(&(info->uni_dir_drive), dir_drive, len_dir_drive+1);
+ make_unistr2(&(info->uni_logon_script), logon_script, len_logon_script+1);
+ make_unistr2(&(info->uni_acct_desc), acct_desc, len_acct_desc+1);
+ make_unistr2(&(info->uni_profile ), profile , len_profile +1);
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+static void net_io_sam_account_info(char *desc, SAM_ACCOUNT_INFO *info, prs_struct *ps, int depth)
+{
+ if (info == NULL) return;
+
+ prs_debug(ps, depth, desc, "net_io_sam_account_info");
+ depth++;
+
+ smb_io_unihdr("hdr_acct_name", &(info->hdr_acct_name), ps, depth);
+ smb_io_unihdr("hdr_full_name", &(info->hdr_full_name), ps, depth);
+
+ prs_uint32("user_rid ", ps, depth, &(info->user_rid ));
+ prs_uint32("group_rid", ps, depth, &(info->group_rid));
+
+ smb_io_unihdr("hdr_home_dir " , &(info->hdr_home_dir ), ps, depth);
+ smb_io_unihdr("hdr_dir_drive" , &(info->hdr_dir_drive), ps, depth);
+ smb_io_unihdr("hdr_logon_script", &(info->hdr_logon_script), ps, depth);
+ smb_io_unihdr("hdr_acct_desc" , &(info->hdr_acct_desc), ps, depth);
+
+ smb_io_time("time_1", &(info->time_1), ps, depth);
+ smb_io_time("time_2", &(info->time_2), ps, depth);
+ smb_io_time("time_3", &(info->time_3), ps, depth);
+
+ prs_uint32("logon_divs ", ps, depth, &(info->logon_divs ));
+ prs_uint32("ptr_logon_hrs", ps, depth, &(info->ptr_logon_hrs));
+
+ smb_io_time("time_4", &(info->time_4), ps, depth);
+ smb_io_time("time_5", &(info->time_5), ps, depth);
+ prs_uint32("acb_info", ps, depth, &(info->acb_info));
+ ps->offset += 36;
+
+ smb_io_unihdr("hdr_comment", &(info->hdr_comment), ps, depth);
+ ps->offset += 12;
+
+ smb_io_bufhdr2("hdr_pwd_info", &(info->hdr_pwd_info), ps, depth);
+ smb_io_bufhdr2("hdr_sec_desc", &(info->hdr_sec_desc), ps, depth);
+ smb_io_unihdr ("hdr_profile ", &(info->hdr_profile) , ps, depth);
+ ps->offset += 36; /* includes that stupid NTTIME, ignore for now */
+
+ smb_io_unistr2("uni_acct_name", &(info->uni_acct_name),
+ info->hdr_acct_name.buffer, ps, depth);
+ smb_io_unistr2("uni_full_name", &(info->uni_full_name),
+ info->hdr_full_name.buffer, ps, depth);
+ smb_io_unistr2("uni_home_dir ", &(info->uni_home_dir ),
+ info->hdr_home_dir .buffer, ps, depth);
+ smb_io_unistr2("uni_dir_drive", &(info->uni_dir_drive),
+ info->hdr_dir_drive.buffer, ps, depth);
+ smb_io_unistr2("uni_logon_script", &(info->uni_logon_script),
+ info->hdr_logon_script.buffer, ps, depth);
+ smb_io_unistr2("uni_acct_desc", &(info->uni_acct_desc),
+ info->hdr_acct_desc.buffer, ps, depth);
+
+ prs_uint32("unknown4", ps, depth, &(info->unknown4));
+ prs_uint32("unknown5", ps, depth, &(info->unknown5));
+
+ smb_io_buffer4("buf_logon_hrs", &(info->buf_logon_hrs),
+ info->ptr_logon_hrs, ps, depth);
+ smb_io_unistr2("uni_comment" , &(info->uni_comment ),
+ info->hdr_comment.buffer, ps, depth);
+ smb_io_buffer4("buf_pwd_info" , &(info->buf_pwd_info ),
+ info->hdr_pwd_info.buffer, ps, depth);
+ smb_io_buffer4("buf_sec_desc" , &(info->buf_sec_desc ),
+ info->hdr_sec_desc.buffer, ps, depth);
+ smb_io_unistr2("uni_profile" , &(info->uni_profile ),
+ info->hdr_profile.buffer, ps, depth);
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+static void net_io_sam_group_mem_info(char *desc, SAM_GROUP_MEM_INFO *info, prs_struct *ps, int depth)
+{
+ int i;
+ fstring tmp;
+
+ if (info == NULL) return;
+
+ prs_debug(ps, depth, desc, "net_io_sam_group_mem_info");
+ depth++;
+
+ prs_align(ps);
+ prs_uint32("ptr_rids ", ps, depth, &(info->ptr_rids ));
+ prs_uint32("ptr_attribs", ps, depth, &(info->ptr_attribs));
+ prs_uint32("num_members", ps, depth, &(info->num_members));
+ ps->offset += 16;
+
+ if (info->ptr_rids != 0)
+ {
+ prs_uint32("num_members2", ps, depth, &(info->num_members2));
+ if (info->num_members2 != info->num_members)
+ {
+ /* RPC fault */
+ return;
+ }
+ SMB_ASSERT_ARRAY(info->rids, info->num_members2);
+
+ for (i = 0; i < info->num_members2; i++)
+ {
+ prs_grow(ps);
+ slprintf(tmp, sizeof(tmp) - 1, "rids[%02d]", i);
+ prs_uint32(tmp, ps, depth, &(info->rids[i]));
+ }
+ }
+
+ if (info->ptr_attribs != 0)
+ {
+ prs_uint32("num_members3", ps, depth, &(info->num_members3));
+ if (info->num_members3 != info->num_members)
+ {
+ /* RPC fault */
+ return;
+ }
+
+ SMB_ASSERT_ARRAY(info->attribs, info->num_members3);
+
+ for (i = 0; i < info->num_members3; i++)
+ {
+ prs_grow(ps);
+ slprintf(tmp, sizeof(tmp) - 1, "attribs[%02d]", i);
+ prs_uint32(tmp, ps, depth, &(info->attribs[i]));
+ }
+ }
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+static void net_io_sam_alias_info(char *desc, SAM_ALIAS_INFO *info, prs_struct *ps, int depth)
+{
+ if (info == NULL) return;
+
+ prs_debug(ps, depth, desc, "net_io_sam_alias_info");
+ depth++;
+
+ smb_io_unihdr ("hdr_als_name", &(info->hdr_als_name), ps, depth);
+ prs_uint32("als_rid", ps, depth, &(info->als_rid));
+ smb_io_bufhdr2("hdr_sec_desc", &(info->hdr_sec_desc), ps, depth);
+ smb_io_unihdr ("hdr_als_desc", &(info->hdr_als_desc), ps, depth);
+ ps->offset += 40;
+
+ smb_io_unistr2("uni_als_name", &(info->uni_als_name),
+ info->hdr_als_name.buffer, ps, depth);
+ smb_io_buffer4("buf_sec_desc", &(info->buf_sec_desc),
+ info->hdr_sec_desc.buffer, ps, depth);
+ smb_io_unistr2("uni_als_desc", &(info->uni_als_desc),
+ info->hdr_als_name.buffer, ps, depth);
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+static void net_io_sam_alias_mem_info(char *desc, SAM_ALIAS_MEM_INFO *info, prs_struct *ps, int depth)
+{
+ int i;
+ fstring tmp;
+
+ if (info == NULL) return;
+
+ prs_debug(ps, depth, desc, "net_io_sam_alias_mem_info");
+ depth++;
+
+ prs_align(ps);
+ prs_uint32("num_members", ps, depth, &(info->num_members));
+ prs_uint32("ptr_members", ps, depth, &(info->ptr_members));
+ ps->offset += 16;
+
+ if (info->ptr_members != 0)
+ {
+ prs_uint32("num_sids", ps, depth, &(info->num_sids));
+ if (info->num_sids != info->num_members)
+ {
+ /* RPC fault */
+ return;
+ }
+
+ SMB_ASSERT_ARRAY(info->ptr_sids, info->num_sids);
+
+ for (i = 0; i < info->num_sids; i++)
+ {
+ prs_grow(ps);
+ slprintf(tmp, sizeof(tmp) - 1, "ptr_sids[%02d]", i);
+ prs_uint32(tmp, ps, depth, &(info->ptr_sids[i]));
+ }
+
+ SMB_ASSERT_ARRAY(info->sids, info->num_sids);
+
+ for (i = 0; i < info->num_sids; i++)
+ {
+ if (info->ptr_sids[i] != 0)
+ {
+ prs_grow(ps);
+ slprintf(tmp, sizeof(tmp) - 1, "sids[%02d]", i);
+ smb_io_dom_sid2(tmp, &(info->sids[i]), ps, depth);
+ }
+ }
+ }
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+static void net_io_sam_delta_ctr(char *desc, SAM_DELTA_CTR *delta, uint32 type, prs_struct *ps, int depth)
+{
+ if (delta == NULL) return;
+
+ prs_debug(ps, depth, desc, "net_io_sam_delta_ctr");
+ depth++;
+
+ switch (type)
+ {
+ case 1:
+ net_io_sam_domain_info("", &(delta->domain_info), ps, depth);
+ break;
+ case 2:
+ net_io_sam_group_info("", &(delta->group_info), ps, depth);
+ break;
+ case 5:
+ net_io_sam_account_info("", &(delta->account_info), ps, depth);
+ break;
+ case 8:
+ net_io_sam_group_mem_info("", &(delta->grp_mem_info), ps, depth);
+ break;
+ case 9:
+ net_io_sam_alias_info("", &(delta->alias_info), ps, depth);
+ break;
+ case 0xC:
+ net_io_sam_alias_mem_info("", &(delta->als_mem_info), ps, depth);
+ break;
+ default:
+ DEBUG(0, ("Replication error: Unknown delta type %x\n", type));
+ }
+
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void net_io_r_sam_sync(char *desc, NET_R_SAM_SYNC *r_s, prs_struct *ps, int depth)
+{
+ int i;
+
+ if (r_s == NULL) return;
+
+ prs_debug(ps, depth, desc, "net_io_r_sam_sync");
+ depth++;
+
+ smb_io_cred("", &(r_s->srv_creds), ps, depth);
+ prs_uint32("sync_context", ps, depth, &(r_s->sync_context));
+
+ prs_uint32("ptr_deltas", ps, depth, &(r_s->ptr_deltas));
+ if (r_s->ptr_deltas != 0)
+ {
+ prs_uint32("num_deltas ", ps, depth, &(r_s->num_deltas ));
+ prs_uint32("ptr_deltas2", ps, depth, &(r_s->ptr_deltas2));
+ if (r_s->ptr_deltas2 != 0)
+ {
+ prs_uint32("num_deltas2", ps, depth, &(r_s->num_deltas2));
+ if (r_s->num_deltas2 != r_s->num_deltas)
+ {
+ /* RPC fault */
+ return;
+ }
+
+ for (i = 0; i < r_s->num_deltas2; i++)
+ {
+ net_io_sam_delta_hdr("", &r_s->hdr_deltas[i], ps, depth);
+ }
+
+ for (i = 0; i < r_s->num_deltas2; i++)
+ {
+ net_io_sam_delta_ctr("", &r_s->deltas[i],
+ r_s->hdr_deltas[i].type3, ps, depth);
+ }
+ }
+ }
+
+ prs_uint32("status", ps, depth, &(r_s->status));
+}
diff --git a/source3/rpc_parse/parse_prs.c b/source3/rpc_parse/parse_prs.c
index ef327f01a1..23a9d5bfdf 100644
--- a/source3/rpc_parse/parse_prs.c
+++ b/source3/rpc_parse/parse_prs.c
@@ -180,7 +180,7 @@ BOOL prs_buffer2(BOOL charmode, char *name, prs_struct *ps, int depth, BUFFER2 *
char *q = mem_data(&(ps->data), ps->offset);
if (q == NULL) return False;
- DBG_RW_PSVAL(charmode, name, depth, ps->offset, ps->io, q, str->buffer, str->buf_len/2)
+ DBG_RW_PCVAL(charmode, name, depth, ps->offset, ps->io, q, str->buffer, str->buf_len)
ps->offset += str->buf_len;
return True;
diff --git a/source3/rpc_parse/parse_reg.c b/source3/rpc_parse/parse_reg.c
index abb00e1572..b97fe3958b 100644
--- a/source3/rpc_parse/parse_reg.c
+++ b/source3/rpc_parse/parse_reg.c
@@ -767,7 +767,7 @@ void make_reg_r_info(REG_R_INFO *r_r,
if (r_r == NULL || os_type == NULL) return;
- len = strlen(os_type) * 2;
+ len = strlen(os_type);
r_r->ptr1 = 1;
r_r->level = level;
@@ -775,11 +775,8 @@ void make_reg_r_info(REG_R_INFO *r_r,
r_r->ptr_type = 1;
make_buffer2(&(r_r->uni_type), os_type, len);
- r_r->ptr2 = 1;
- r_r->unknown_0 = len;
-
- r_r->ptr3 = 1;
- r_r->unknown_1 = len;
+ r_r->ptr2 = r_r->ptr3 = 1;
+ r_r->unknown_0 = r_r->unknown_1 = len * 2;
r_r->status = status;
}
diff --git a/source3/rpcclient/cmd_netlogon.c b/source3/rpcclient/cmd_netlogon.c
index 1ad71b7f4f..be5bf8596a 100644
--- a/source3/rpcclient/cmd_netlogon.c
+++ b/source3/rpcclient/cmd_netlogon.c
@@ -101,7 +101,7 @@ void cmd_netlogon_login_test(struct client_info *info)
{
unsigned char new_trust_passwd[16];
generate_random_buffer(new_trust_passwd, 16, True);
- res = res ? cli_nt_srv_pwset(smb_cli, nt_pipe_fnum, new_trust_passwd) : False;
+ res = res ? cli_nt_srv_pwset(smb_cli, nt_pipe_fnum, new_trust_passwd, SEC_CHAN_WKSTA) : False;
if (res)
{
@@ -174,3 +174,31 @@ void cmd_netlogon_domain_test(struct client_info *info)
nt_trust_dom, BOOLSTR(res));
}
+/****************************************************************************
+experimental SAM synchronisation.
+****************************************************************************/
+void cmd_sam_sync(struct client_info *info)
+{
+ uint16 nt_pipe_fnum;
+ BOOL res = True;
+ unsigned char trust_passwd[16];
+
+ DEBUG(5,("Attempting SAM Synchronisation with PDC\n"));
+
+ res = res ? trust_get_passwd(trust_passwd, smb_cli->domain, info->myhostname) : False;
+
+ /* open NETLOGON session. negotiate credentials */
+ res = res ? cli_nt_session_open(smb_cli, PIPE_NETLOGON, &nt_pipe_fnum) : False;
+
+ res = res ? cli_nt_setup_creds(smb_cli, nt_pipe_fnum, smb_cli->mach_acct,
+ trust_passwd, SEC_CHAN_BDC) : False;
+
+ res = res ? cli_net_sam_sync(smb_cli, nt_pipe_fnum, 0) : False;
+
+ memset(trust_passwd, 0, 16);
+
+ /* close the session */
+ cli_nt_session_close(smb_cli, nt_pipe_fnum);
+
+ fprintf(out_hnd,"cmd_sam_sync: test succeeded: %s\n", BOOLSTR(res));
+}
diff --git a/source3/rpcclient/display.c b/source3/rpcclient/display.c
index 060dac8d55..831378ab96 100644
--- a/source3/rpcclient/display.c
+++ b/source3/rpcclient/display.c
@@ -1476,7 +1476,7 @@ static void print_reg_value(FILE *out_hnd, char *val_name, uint32 val_type, BUFF
{
case 0x01: /* unistr */
{
- unistr_to_ascii(valstr, value->buffer,
+ unibuf_to_ascii(valstr, value->buffer,
MIN(value->buf_len, sizeof(valstr)-1));
fprintf(out_hnd,"\t%s:\t%s:\t%s\n", val_name, type, valstr);
break;
diff --git a/source3/rpcclient/rpcclient.c b/source3/rpcclient/rpcclient.c
index a0e3fe90a3..870555e6e2 100644
--- a/source3/rpcclient/rpcclient.c
+++ b/source3/rpcclient/rpcclient.c
@@ -142,6 +142,7 @@ struct
{"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)"},
+ {"samsync", cmd_sam_sync, "SAM Synchronization Test (experimental)"},
{"quit", cmd_quit, "logoff the server"},
{"q", cmd_quit, "logoff the server"},
{"exit", cmd_quit, "logoff the server"},