summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/include/rpc_misc.h9
-rw-r--r--source3/include/rpc_netlogon.h47
-rw-r--r--source3/rpc_parse/parse_misc.c62
-rw-r--r--source3/rpc_parse/parse_net.c46
-rw-r--r--source3/utils/net_rpc_samsync.c114
5 files changed, 259 insertions, 19 deletions
diff --git a/source3/include/rpc_misc.h b/source3/include/rpc_misc.h
index 0c6eee3650..ee8208e90e 100644
--- a/source3/include/rpc_misc.h
+++ b/source3/include/rpc_misc.h
@@ -395,6 +395,15 @@ typedef struct bufhdr2_info
}
BUFHDR2;
+/* BUFHDR4 - another buffer header */
+typedef struct bufhdr4_info
+{
+ uint32 size;
+ uint32 buffer;
+
+}
+BUFHDR4;
+
/* BUFFER4 - simple length and buffer */
typedef struct buffer4_info
{
diff --git a/source3/include/rpc_netlogon.h b/source3/include/rpc_netlogon.h
index 97b2523d72..b865d05b34 100644
--- a/source3/include/rpc_netlogon.h
+++ b/source3/include/rpc_netlogon.h
@@ -597,6 +597,27 @@ typedef struct sam_delta_hdr_info
} SAM_DELTA_HDR;
+/* LOCKOUT_STRING */
+typedef struct account_lockout_string {
+ uint32 array_size;
+ uint32 offset;
+ uint32 length;
+/* uint16 *bindata; */
+ UINT64_S lockout_duration;
+ UINT64_S reset_count;
+ uint32 bad_attempt_lockout;
+ uint32 dummy;
+
+} LOCKOUT_STRING;
+
+/* HDR_LOCKOUT_STRING */
+typedef struct hdr_account_lockout_string {
+ uint16 size;
+ uint16 length;
+ uint32 buffer;
+
+} HDR_LOCKOUT_STRING;
+
/* SAM_DOMAIN_INFO (0x1) */
typedef struct sam_domain_info_info
{
@@ -610,16 +631,32 @@ typedef struct sam_domain_info_info
UINT64_S min_pwd_age;
UINT64_S dom_mod_count;
NTTIME creation_time;
+ uint32 security_information;
- BUFHDR2 hdr_sec_desc; /* security descriptor */
- UNIHDR hdr_unknown;
- uint8 reserved[40];
+ BUFHDR4 hdr_sec_desc; /* security descriptor */
+
+ HDR_LOCKOUT_STRING hdr_account_lockout;
+
+ UNIHDR hdr_unknown2;
+ UNIHDR hdr_unknown3;
+ UNIHDR hdr_unknown4;
UNISTR2 uni_dom_name;
- UNISTR2 buf_oem_info; /* never seen */
+ UNISTR2 buf_oem_info;
BUFFER4 buf_sec_desc;
- UNISTR2 buf_unknown;
+
+ LOCKOUT_STRING account_lockout;
+
+ UNISTR2 buf_unknown2;
+ UNISTR2 buf_unknown3;
+ UNISTR2 buf_unknown4;
+
+ uint32 logon_chgpass;
+ uint32 unknown6;
+ uint32 unknown7;
+ uint32 unknown8;
+
} SAM_DOMAIN_INFO;
diff --git a/source3/rpc_parse/parse_misc.c b/source3/rpc_parse/parse_misc.c
index 17a8f624ae..0ebc16581b 100644
--- a/source3/rpc_parse/parse_misc.c
+++ b/source3/rpc_parse/parse_misc.c
@@ -1109,6 +1109,53 @@ BOOL init_unistr2_array(UNISTR2_ARRAY *array,
return True;
}
+BOOL smb_io_lockout_string_hdr(const char *desc, HDR_LOCKOUT_STRING *hdr_account_lockout, prs_struct *ps, int depth)
+{
+ prs_debug(ps, depth, desc, "smb_io_lockout_string_hdr");
+ depth++;
+
+ if(!prs_align(ps))
+ return False;
+
+ if(!prs_uint16("size", ps, depth, &hdr_account_lockout->size))
+ return False;
+ if(!prs_uint16("length", ps, depth, &hdr_account_lockout->length))
+ return False;
+ if(!prs_uint32("buffer", ps, depth, &hdr_account_lockout->buffer))
+ return False;
+
+ return True;
+}
+
+BOOL smb_io_account_lockout_str(const char *desc, LOCKOUT_STRING *account_lockout, uint32 buffer, prs_struct *ps, int depth)
+{
+ prs_debug(ps, depth, desc, "smb_io_account_lockout_string");
+ depth++;
+
+ if(!prs_uint32("array_size", ps, depth, &account_lockout->array_size))
+ return False;
+
+ if(!prs_uint32("offset", ps, depth, &account_lockout->offset))
+ return False;
+ if(!prs_uint32("length", ps, depth, &account_lockout->length))
+ return False;
+
+ if (!prs_uint64("lockout_duration", ps, depth, &account_lockout->lockout_duration))
+ return False;
+ if (!prs_uint64("reset_count", ps, depth, &account_lockout->reset_count))
+ return False;
+ if (!prs_uint32("bad_attempt_lockout", ps, depth, &account_lockout->bad_attempt_lockout))
+ return False;
+ if (!prs_uint32("dummy", ps, depth, &account_lockout->dummy))
+ return False;
+#if 0
+ if(!prs_uint16s (False, "bindata", ps, depth, &account_lockout->bindata, length))
+ return False;
+#endif
+
+ return True;
+}
+
/*******************************************************************
Reads or writes a UNISTR2_ARRAY structure.
********************************************************************/
@@ -1695,6 +1742,21 @@ BOOL smb_io_bufhdr2(const char *desc, BUFHDR2 *hdr, prs_struct *ps, int depth)
}
/*******************************************************************
+reads or writes a BUFHDR4 structure.
+********************************************************************/
+BOOL smb_io_bufhdr4(const char *desc, BUFHDR4 *hdr, prs_struct *ps, int depth)
+{
+ prs_debug(ps, depth, desc, "smb_io_bufhdr4");
+ depth++;
+
+ prs_align(ps);
+ prs_uint32("size", ps, depth, &(hdr->size));
+ prs_uint32("buffer", ps, depth, &(hdr->buffer));
+
+ return True;
+}
+
+/*******************************************************************
reads or writes a BUFFER4 structure.
********************************************************************/
BOOL smb_io_buffer4(const char *desc, BUFFER4 *buf4, uint32 buffer, prs_struct *ps, int depth)
diff --git a/source3/rpc_parse/parse_net.c b/source3/rpc_parse/parse_net.c
index 7e5eec3e6d..5f1d4b622e 100644
--- a/source3/rpc_parse/parse_net.c
+++ b/source3/rpc_parse/parse_net.c
@@ -1937,15 +1937,26 @@ static BOOL net_io_sam_domain_info(const char *desc, SAM_DOMAIN_INFO * info,
return False;
if (!smb_io_time("creation_time", &info->creation_time, ps, depth))
return False;
-
- if (!smb_io_bufhdr2("hdr_sec_desc", &info->hdr_sec_desc, ps, depth))
- return False;
- if (!smb_io_unihdr("hdr_unknown", &info->hdr_unknown, ps, depth))
- return False;
-
- if (ps->data_offset + 40 > ps->buffer_size)
- return False;
- ps->data_offset += 40;
+ if (!prs_uint32("security_information", ps, depth, &info->security_information))
+ return False;
+ if (!smb_io_bufhdr4("hdr_sec_desc", &info->hdr_sec_desc, ps, depth))
+ return False;
+ if (!smb_io_lockout_string_hdr("hdr_account_lockout_string", &info->hdr_account_lockout, ps, depth))
+ return False;
+ if (!smb_io_unihdr("hdr_unknown2", &info->hdr_unknown2, ps, depth))
+ return False;
+ if (!smb_io_unihdr("hdr_unknown3", &info->hdr_unknown3, ps, depth))
+ return False;
+ if (!smb_io_unihdr("hdr_unknown4", &info->hdr_unknown4, ps, depth))
+ return False;
+ if (!prs_uint32("logon_chgpass", ps, depth, &info->logon_chgpass))
+ return False;
+ if (!prs_uint32("unknown6", ps, depth, &info->unknown6))
+ return False;
+ if (!prs_uint32("unknown7", ps, depth, &info->unknown7))
+ return False;
+ if (!prs_uint32("unknown8", ps, depth, &info->unknown8))
+ return False;
if (!smb_io_unistr2("uni_dom_name", &info->uni_dom_name,
info->hdr_dom_name.buffer, ps, depth))
@@ -1957,9 +1968,20 @@ static BOOL net_io_sam_domain_info(const char *desc, SAM_DOMAIN_INFO * info,
if (!smb_io_buffer4("buf_sec_desc", &info->buf_sec_desc,
info->hdr_sec_desc.buffer, ps, depth))
return False;
- if (!smb_io_unistr2("buf_unknown", &info->buf_unknown,
- info->hdr_unknown.buffer, ps, depth))
- return False;
+
+ if (!smb_io_account_lockout_str("account_lockout", &info->account_lockout,
+ info->hdr_account_lockout.buffer, ps, depth))
+ return False;
+
+ if (!smb_io_unistr2("buf_unknown2", &info->buf_unknown2,
+ info->hdr_unknown2.buffer, ps, depth))
+ return False;
+ if (!smb_io_unistr2("buf_unknown3", &info->buf_unknown3,
+ info->hdr_unknown3.buffer, ps, depth))
+ return False;
+ if (!smb_io_unistr2("buf_unknown4", &info->buf_unknown4,
+ info->hdr_unknown4.buffer, ps, depth))
+ return False;
return True;
}
diff --git a/source3/utils/net_rpc_samsync.c b/source3/utils/net_rpc_samsync.c
index d7af528ff1..3c98ec9e71 100644
--- a/source3/utils/net_rpc_samsync.c
+++ b/source3/utils/net_rpc_samsync.c
@@ -36,6 +36,45 @@ static void display_group_mem_info(uint32 rid, SAM_GROUP_MEM_INFO *g)
d_printf("\n");
}
+
+static const char *display_time(NTTIME *nttime)
+{
+ static fstring string;
+
+ float high;
+ float low;
+ int sec;
+ int days, hours, mins, secs;
+ int offset = 1;
+
+ if (nttime->high==0 && nttime->low==0)
+ return "Now";
+
+ if (nttime->high==0x80000000 && nttime->low==0)
+ return "Never";
+
+ high = 65536;
+ high = high/10000;
+ high = high*65536;
+ high = high/1000;
+ high = high * (~nttime->high);
+
+ low = ~nttime->low;
+ low = low/(1000*1000*10);
+
+ sec=high+low;
+ sec+=offset;
+
+ days=sec/(60*60*24);
+ hours=(sec - (days*60*60*24)) / (60*60);
+ mins=(sec - (days*60*60*24) - (hours*60*60) ) / 60;
+ secs=sec - (days*60*60*24) - (hours*60*60) - (mins*60);
+
+ fstr_sprintf(string, "%u days, %u hours, %u minutes, %u seconds", days, hours, mins, secs);
+ return (string);
+}
+
+
static void display_alias_info(uint32 rid, SAM_ALIAS_INFO *a)
{
d_printf("Alias '%s' ", unistr2_static(&a->uni_als_name));
@@ -81,7 +120,25 @@ static void display_account_info(uint32 rid, SAM_ACCOUNT_INFO *a)
static void display_domain_info(SAM_DOMAIN_INFO *a)
{
+ time_t u_logout;
+
+ u_logout = nt_time_to_unix_abs((NTTIME *)&a->force_logoff);
+
d_printf("Domain name: %s\n", unistr2_static(&a->uni_dom_name));
+
+ d_printf("Minimal Password Length: %d\n", a->min_pwd_len);
+ d_printf("Password History Length: %d\n", a->pwd_history_len);
+
+ d_printf("Force Logoff: %d\n", (int)u_logout);
+
+ d_printf("Max Password Age: %s\n", display_time((NTTIME *)&a->max_pwd_age));
+ d_printf("Min Password Age: %s\n", display_time((NTTIME *)&a->min_pwd_age));
+
+ d_printf("Lockout Time: %s\n", display_time((NTTIME *)&a->account_lockout.lockout_duration));
+ d_printf("Lockout Reset Time: %s\n", display_time((NTTIME *)&a->account_lockout.reset_count));
+
+ d_printf("Bad Attempt Lockout: %d\n", a->account_lockout.bad_attempt_lockout);
+ d_printf("User must logon to change password: %d\n", a->logon_chgpass);
}
static void display_group_info(uint32 rid, SAM_GROUP_INFO *a)
@@ -897,6 +954,58 @@ fetch_alias_mem(uint32 rid, SAM_ALIAS_MEM_INFO *delta, DOM_SID dom_sid)
return NT_STATUS_OK;
}
+static NTSTATUS fetch_domain_info(uint32 rid, SAM_DOMAIN_INFO *delta)
+{
+ time_t u_max_age, u_min_age, u_logout, u_lockoutreset, u_lockouttime;
+ NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
+ pstring domname;
+
+ u_max_age = nt_time_to_unix_abs((NTTIME *)&delta->max_pwd_age);
+ u_min_age = nt_time_to_unix_abs((NTTIME *)&delta->min_pwd_age);
+ u_logout = nt_time_to_unix_abs((NTTIME *)&delta->force_logoff);
+ u_lockoutreset = nt_time_to_unix_abs((NTTIME *)&delta->account_lockout.reset_count);
+ u_lockouttime = nt_time_to_unix_abs((NTTIME *)&delta->account_lockout.lockout_duration);
+
+ unistr2_to_ascii(domname, &delta->uni_dom_name, sizeof(domname) - 1);
+
+ /* we don't handle BUILTIN account policies */
+ if (!strequal(domname, get_global_sam_name())) {
+ printf("skipping SAM_DOMAIN_INFO delta for '%s' (is not my domain)\n", domname);
+ return NT_STATUS_OK;
+ }
+
+
+ if (!account_policy_set(AP_PASSWORD_HISTORY, delta->pwd_history_len))
+ return nt_status;
+
+ if (!account_policy_set(AP_MIN_PASSWORD_LEN, delta->min_pwd_len))
+ return nt_status;
+
+ if (!account_policy_set(AP_MAX_PASSWORD_AGE, (uint32)u_max_age))
+ return nt_status;
+
+ if (!account_policy_set(AP_MIN_PASSWORD_AGE, (uint32)u_min_age))
+ return nt_status;
+
+ if (!account_policy_set(AP_TIME_TO_LOGOUT, (uint32)u_logout))
+ return nt_status;
+
+ if (!account_policy_set(AP_BAD_ATTEMPT_LOCKOUT, delta->account_lockout.bad_attempt_lockout))
+ return nt_status;
+
+ if (!account_policy_set(AP_RESET_COUNT_TIME, (uint32)u_lockoutreset/60))
+ return nt_status;
+
+ if (!account_policy_set(AP_LOCK_ACCOUNT_DURATION, (uint32)u_lockouttime/60))
+ return nt_status;
+
+ if (!account_policy_set(AP_USER_MUST_LOGON_TO_CHG_PASS, delta->logon_chgpass))
+ return nt_status;
+
+ return NT_STATUS_OK;
+}
+
+
static void
fetch_sam_entry(SAM_DELTA_HDR *hdr_delta, SAM_DELTA_CTR *delta,
DOM_SID dom_sid)
@@ -922,10 +1031,11 @@ fetch_sam_entry(SAM_DELTA_HDR *hdr_delta, SAM_DELTA_CTR *delta,
fetch_alias_mem(hdr_delta->target_rid,
&delta->als_mem_info, dom_sid);
break;
- /* The following types are recognised but not handled */
case SAM_DELTA_DOMAIN_INFO:
- d_printf("SAM_DELTA_DOMAIN_INFO not handled\n");
+ fetch_domain_info(hdr_delta->target_rid,
+ &delta->domain_info);
break;
+ /* The following types are recognised but not handled */
case SAM_DELTA_RENAME_GROUP:
d_printf("SAM_DELTA_RENAME_GROUP not handled\n");
break;