From 5cfe36d09d1de8c6a82152d4941c1563111f4364 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 7 Nov 2003 18:32:23 +0000 Subject: [PATCH] Handle munged dial string. Patch from Aur?lien Degr?mont with memory leak fixes by me. Jeremy. (This used to be commit e591854eda8568ed1a4ad6b9de64e523c02b4392) --- source3/rpc_parse/parse_misc.c | 21 +++++++++++++ source3/rpc_parse/parse_samr.c | 19 ++++++++---- source3/rpc_server/srv_samr_nt.c | 37 ++++++++++++++++++++++- source3/rpc_server/srv_samr_util.c | 60 +++++++++++++++++++++++++++++++------- 4 files changed, 121 insertions(+), 16 deletions(-) diff --git a/source3/rpc_parse/parse_misc.c b/source3/rpc_parse/parse_misc.c index e1825355320..86ea83d7aa8 100644 --- a/source3/rpc_parse/parse_misc.c +++ b/source3/rpc_parse/parse_misc.c @@ -1001,6 +1001,27 @@ void init_unistr2_from_unistr(UNISTR2 *to, const UNISTR *from) } /******************************************************************* + Inits a UNISTR2 structure from a DATA_BLOB. + The length of the data_blob must count the bytes of the buffer. + Copies the blob data. +********************************************************************/ + +void init_unistr2_from_datablob(UNISTR2 *str, DATA_BLOB *blob) +{ + /* Allocs the unistring */ + init_unistr2(str, NULL, UNI_FLAGS_NONE); + + /* Sets the values */ + str->uni_str_len = blob->length / sizeof(uint16); + str->uni_max_len = str->uni_str_len; + str->offset = 0; + str->buffer = (uint16 *) memdup(blob->data, blob->length); + if (!str->buffer) { + smb_panic("init_unistr2_from_datablob: malloc fail\n"); + } +} + +/******************************************************************* Reads or writes a UNISTR2 structure. XXXX NOTE: UNISTR2 structures need NOT be null-terminated. the uni_str_len member tells you how long the string is; diff --git a/source3/rpc_parse/parse_samr.c b/source3/rpc_parse/parse_samr.c index 939b652a1e3..73107f8f61e 100644 --- a/source3/rpc_parse/parse_samr.c +++ b/source3/rpc_parse/parse_samr.c @@ -5485,6 +5485,8 @@ void init_sam_user_info23A(SAM_USER_INFO_23 * usr, NTTIME * logon_time, /* all z LOGON_HRS * hrs, uint16 bad_password_count, uint16 logon_count, char newpass[516], uint32 unknown_6) { + DATA_BLOB blob = base64_decode_data_blob(mung_dial); + usr->logon_time = *logon_time; /* all zeros */ usr->logoff_time = *logoff_time; /* all zeros */ usr->kickoff_time = *kickoff_time; /* all zeros */ @@ -5544,9 +5546,11 @@ void init_sam_user_info23A(SAM_USER_INFO_23 * usr, NTTIME * logon_time, /* all z init_unistr2(&usr->uni_unknown_str, unk_str, UNI_FLAGS_NONE); init_uni_hdr(&usr->hdr_unknown_str, &usr->uni_unknown_str); - init_unistr2(&usr->uni_munged_dial, mung_dial, UNI_FLAGS_NONE); + init_unistr2_from_datablob(&usr->uni_munged_dial, &blob); init_uni_hdr(&usr->hdr_munged_dial, &usr->uni_munged_dial); + data_blob_free(&blob); + usr->unknown_6 = unknown_6; /* 0x0000 04ec */ usr->padding4 = 0; @@ -5934,6 +5938,7 @@ NTSTATUS init_sam_user_info21A(SAM_USER_INFO_21 *usr, SAM_ACCOUNT *pw, DOM_SID * const char* description = pdb_get_acct_desc(pw); const char* workstations = pdb_get_workstations(pw); const char* munged_dial = pdb_get_munged_dial(pw); + DATA_BLOB blob = base64_decode_data_blob(munged_dial); uint32 user_rid; const DOM_SID *user_sid; @@ -5970,6 +5975,7 @@ NTSTATUS init_sam_user_info21A(SAM_USER_INFO_21 *usr, SAM_ACCOUNT *pw, DOM_SID * user_name, sid_to_string(user_sid_string, user_sid), sid_to_string(domain_sid_string, domain_sid))); + data_blob_free(&blob); return NT_STATUS_UNSUCCESSFUL; } @@ -5983,6 +5989,7 @@ NTSTATUS init_sam_user_info21A(SAM_USER_INFO_21 *usr, SAM_ACCOUNT *pw, DOM_SID * user_name, sid_to_string(group_sid_string, group_sid), sid_to_string(domain_sid_string, domain_sid))); + data_blob_free(&blob); return NT_STATUS_UNSUCCESSFUL; } @@ -6042,8 +6049,9 @@ NTSTATUS init_sam_user_info21A(SAM_USER_INFO_21 *usr, SAM_ACCOUNT *pw, DOM_SID * init_unistr2(&usr->uni_unknown_str, NULL, UNI_STR_TERMINATE); init_uni_hdr(&usr->hdr_unknown_str, &usr->uni_unknown_str); - init_unistr2(&usr->uni_munged_dial, munged_dial, UNI_STR_TERMINATE); + init_unistr2_from_datablob(&usr->uni_munged_dial, &blob); init_uni_hdr(&usr->hdr_munged_dial, &usr->uni_munged_dial); + data_blob_free(&blob); usr->unknown_6 = pdb_get_unknown_6(pw); usr->padding4 = 0; @@ -6184,10 +6192,11 @@ static BOOL sam_io_user_info21(const char *desc, SAM_USER_INFO_21 * usr, void init_sam_user_info20A(SAM_USER_INFO_20 *usr, SAM_ACCOUNT *pw) { const char *munged_dial = pdb_get_munged_dial(pw); - - init_unistr2(&usr->uni_munged_dial, munged_dial, UNI_STR_TERMINATE); + DATA_BLOB blob = base64_decode_data_blob(munged_dial); + + init_unistr2_from_datablob(&usr->uni_munged_dial, &blob); init_uni_hdr(&usr->hdr_munged_dial, &usr->uni_munged_dial); - + data_blob_free(&blob); } /******************************************************************* diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c index 71e5bc7d70b..446eff9045e 100644 --- a/source3/rpc_server/srv_samr_nt.c +++ b/source3/rpc_server/srv_samr_nt.c @@ -2789,6 +2789,38 @@ static BOOL set_unix_primary_group(SAM_ACCOUNT *sampass) /******************************************************************* + set_user_info_20 + ********************************************************************/ + +static BOOL set_user_info_20(SAM_USER_INFO_20 *id20, DOM_SID *sid) +{ + SAM_ACCOUNT *pwd = NULL; + + if (id20 == NULL) { + DEBUG(5, ("set_user_info_20: NULL id20\n")); + return False; + } + + pdb_init_sam(&pwd); + + if (!pdb_getsampwsid(pwd, sid)) { + pdb_free_sam(&pwd); + return False; + } + + copy_id20_to_sam_passwd(pwd, id20); + + /* write the change out */ + if(!pdb_update_sam_account(pwd)) { + pdb_free_sam(&pwd); + return False; + } + + pdb_free_sam(&pwd); + + return True; +} +/******************************************************************* set_user_info_21 ********************************************************************/ @@ -3091,6 +3123,10 @@ NTSTATUS _samr_set_userinfo2(pipes_struct *p, SAMR_Q_SET_USERINFO2 *q_u, SAMR_R_ if (!set_user_info_21(ctr->info.id21, &sid)) return NT_STATUS_ACCESS_DENIED; break; + case 20: + if (!set_user_info_20(ctr->info.id20, &sid)) + return NT_STATUS_ACCESS_DENIED; + break; case 16: if (!set_user_info_10(ctr->info.id10, &sid)) return NT_STATUS_ACCESS_DENIED; @@ -4537,4 +4573,3 @@ NTSTATUS _samr_set_dom_info(pipes_struct *p, SAMR_Q_SET_DOMAIN_INFO *q_u, SAMR_R return r_u->status; } - diff --git a/source3/rpc_server/srv_samr_util.c b/source3/rpc_server/srv_samr_util.c index db6649073e9..82f93a5b4c7 100644 --- a/source3/rpc_server/srv_samr_util.c +++ b/source3/rpc_server/srv_samr_util.c @@ -31,6 +31,36 @@ (!old_string && new_string) ||\ (old_string && new_string && (strcmp(old_string, new_string) != 0)) +#define STRING_CHANGED_NC(s1,s2) ((s1) && !(s2)) ||\ + (!(s1) && (s2)) ||\ + ((s1) && (s2) && (strcmp((s1), (s2)) != 0)) + +/************************************************************* + Copies a SAM_USER_INFO_20 to a SAM_ACCOUNT +**************************************************************/ + +void copy_id20_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_20 *from) +{ + const char *old_string; + char *new_string; + DATA_BLOB mung; + + if (from == NULL || to == NULL) + return; + + if (from->hdr_munged_dial.buffer) { + old_string = pdb_get_munged_dial(to); + mung.length = from->hdr_munged_dial.uni_str_len; + mung.data = (uint8 *) from->uni_munged_dial.buffer; + new_string = base64_encode_data_blob(mung); + DEBUG(10,("INFO_20 UNI_MUNGED_DIAL: %s -> %s\n",old_string, new_string)); + if (STRING_CHANGED_NC(old_string,new_string)) + pdb_set_munged_dial(to , new_string, PDB_CHANGED); + + SAFE_FREE(new_string); + } +} + /************************************************************* Copies a SAM_USER_INFO_21 to a SAM_ACCOUNT **************************************************************/ @@ -39,6 +69,7 @@ void copy_id21_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_21 *from) { time_t unix_time, stored_time; const char *old_string, *new_string; + DATA_BLOB mung; if (from == NULL || to == NULL) return; @@ -162,11 +193,16 @@ void copy_id21_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_21 *from) } if (from->hdr_munged_dial.buffer) { + char *newstr; old_string = pdb_get_munged_dial(to); - new_string = unistr2_static(&from->uni_munged_dial); - DEBUG(10,("INFO_21 UNI_MUNGED_DIAL: %s -> %s\n",old_string, new_string)); - if (STRING_CHANGED) - pdb_set_munged_dial(to , new_string, PDB_CHANGED); + mung.length = from->hdr_munged_dial.uni_str_len; + mung.data = (uint8 *) from->uni_munged_dial.buffer; + newstr = base64_encode_data_blob(mung); + DEBUG(10,("INFO_21 UNI_MUNGED_DIAL: %s -> %s\n",old_string, newstr)); + if (STRING_CHANGED_NC(old_string,newstr)) + pdb_set_munged_dial(to , newstr, PDB_CHANGED); + + SAFE_FREE(newstr); } if (from->user_rid == 0) { @@ -250,6 +286,7 @@ void copy_id23_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_23 *from) { time_t unix_time, stored_time; const char *old_string, *new_string; + DATA_BLOB mung; if (from == NULL || to == NULL) return; @@ -373,11 +410,16 @@ void copy_id23_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_23 *from) } if (from->hdr_munged_dial.buffer) { + char *newstr; old_string = pdb_get_munged_dial(to); - new_string = unistr2_static(&from->uni_munged_dial); - DEBUG(10,("INFO_23 UNI_MUNGED_DIAL: %s -> %s\n",old_string, new_string)); - if (STRING_CHANGED) - pdb_set_munged_dial(to , new_string, PDB_CHANGED); + mung.length = from->hdr_munged_dial.uni_str_len; + mung.data = (uint8 *) from->uni_munged_dial.buffer; + newstr = base64_encode_data_blob(mung); + DEBUG(10,("INFO_23 UNI_MUNGED_DIAL: %s -> %s\n",old_string, newstr)); + if (STRING_CHANGED_NC(old_string, newstr)) + pdb_set_munged_dial(to , newstr, PDB_CHANGED); + + SAFE_FREE(newstr); } if (from->user_rid == 0) { @@ -450,5 +492,3 @@ void copy_id23_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_23 *from) DEBUG(10,("INFO_23 PADDING_4: %08X\n",from->padding4)); } - - -- 2.11.4.GIT