From d4ac326d46faab010eeeb24c893ab13bbbf0337e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 8 Jul 2004 21:01:30 +0000 Subject: r1412: Fix password history list in tdbsam. Fix some memory leaks. Add my (C) to a header file that was at least 50% mine :-). Jeremy. (This used to be commit 8ee6060977ec8e65082f3ad09e1e1ccf5b4672ed) --- source3/include/ntdomain.h | 110 +++++++++++++++++--------------------- source3/lib/account_pol.c | 27 +++++++++- source3/passdb/passdb.c | 23 ++++++-- source3/passdb/pdb_tdb.c | 3 ++ source3/rpc_server/srv_pipe_hnd.c | 3 -- source3/utils/pdbedit.c | 5 ++ 6 files changed, 102 insertions(+), 69 deletions(-) diff --git a/source3/include/ntdomain.h b/source3/include/ntdomain.h index 084e56b51e..a63272fd18 100644 --- a/source3/include/ntdomain.h +++ b/source3/include/ntdomain.h @@ -4,6 +4,7 @@ Copyright (C) Andrew Tridgell 1992-1997 Copyright (C) Luke Kenneth Casson Leighton 1996-1997 Copyright (C) Paul Ashton 1997 + Copyright (C) Jeremy Allison 200-2004 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -23,19 +24,17 @@ #ifndef _NT_DOMAIN_H /* _NT_DOMAIN_H */ #define _NT_DOMAIN_H -struct uuid -{ - uint32 time_low; - uint16 time_mid; - uint16 time_hi_and_version; - uint8 clock_seq[2]; - uint8 node[6]; +struct uuid { + uint32 time_low; + uint16 time_mid; + uint16 time_hi_and_version; + uint8 clock_seq[2]; + uint8 node[6]; }; #define UUID_SIZE 16 #define UUID_FLAT_SIZE 16 -typedef struct uuid_flat -{ +typedef struct uuid_flat { uint8 info[UUID_FLAT_SIZE]; } UUID_FLAT; @@ -54,8 +53,7 @@ typedef struct uuid_flat * in the NTDOM branch - it didn't belong there. */ -typedef struct _prs_struct -{ +typedef struct _prs_struct { BOOL io; /* parsing in or out of data stream */ /* * If the (incoming) data is big-endian. On output we are @@ -109,49 +107,47 @@ typedef struct _output_data { } output_data; typedef struct _input_data { - /* - * This is the current incoming pdu. The data here - * is collected via multiple writes until a complete - * pdu is seen, then the data is copied into the in_data - * structure. The maximum size of this is 0x1630 (MAX_PDU_FRAG_LEN). - */ - unsigned char current_in_pdu[MAX_PDU_FRAG_LEN]; - - /* - * The amount of data needed to complete the in_pdu. - * If this is zero, then we are at the start of a new - * pdu. - */ - uint32 pdu_needed_len; - - /* - * The amount of data received so far in the in_pdu. - * If this is zero, then we are at the start of a new - * pdu. - */ - uint32 pdu_received_len; - - /* - * This is the collection of input data with all - * the rpc headers and auth footers removed. - * The maximum length of this (1Mb) is strictly enforced. - */ - prs_struct data; + /* + * This is the current incoming pdu. The data here + * is collected via multiple writes until a complete + * pdu is seen, then the data is copied into the in_data + * structure. The maximum size of this is 0x1630 (MAX_PDU_FRAG_LEN). + */ + unsigned char current_in_pdu[MAX_PDU_FRAG_LEN]; + + /* + * The amount of data needed to complete the in_pdu. + * If this is zero, then we are at the start of a new + * pdu. + */ + uint32 pdu_needed_len; + + /* + * The amount of data received so far in the in_pdu. + * If this is zero, then we are at the start of a new + * pdu. + */ + uint32 pdu_received_len; + + /* + * This is the collection of input data with all + * the rpc headers and auth footers removed. + * The maximum length of this (1Mb) is strictly enforced. + */ + prs_struct data; } input_data; /* * Handle database - stored per pipe. */ -struct policy -{ - struct policy *next, *prev; +struct policy { + struct policy *next, *prev; - POLICY_HND pol_hnd; - - void *data_ptr; - void (*free_fn)(void *); + POLICY_HND pol_hnd; + void *data_ptr; + void (*free_fn)(void *); }; struct handle_list { @@ -161,8 +157,7 @@ struct handle_list { }; /* Domain controller authentication protocol info */ -struct dcinfo -{ +struct dcinfo { DOM_CHAL clnt_chal; /* Initial challenge received from client */ DOM_CHAL srv_chal; /* Initial server challenge */ DOM_CRED clnt_cred; /* Last client credential */ @@ -198,8 +193,7 @@ typedef struct pipe_rpc_fns { * NamedPipes. */ -typedef struct pipes_struct -{ +typedef struct pipes_struct { struct pipes_struct *next, *prev; connection_struct *conn; @@ -291,8 +285,7 @@ typedef struct pipes_struct } pipes_struct; -typedef struct smb_np_struct -{ +typedef struct smb_np_struct { struct smb_np_struct *next, *prev; int pnum; connection_struct *conn; @@ -368,18 +361,15 @@ typedef struct smb_np_struct } smb_np_struct; -struct api_struct -{ - const char *name; - uint8 opnum; - BOOL (*fn) (pipes_struct *); +struct api_struct { + const char *name; + uint8 opnum; + BOOL (*fn) (pipes_struct *); }; -typedef struct -{ +typedef struct { uint32 rid; const char *name; - } rid_name; /* diff --git a/source3/lib/account_pol.c b/source3/lib/account_pol.c index c2c63493a6..8d5b963da2 100644 --- a/source3/lib/account_pol.c +++ b/source3/lib/account_pol.c @@ -81,6 +81,30 @@ static const struct { {0, NULL} }; +char *account_policy_names_list(void) +{ + char *nl, *p; + int i; + size_t len = 0; + + for (i=0; account_policy_names[i].string; i++) { + len += strlen(account_policy_names[i].string) + 1; + } + len++; + nl = malloc(len); + if (!nl) { + return NULL; + } + p = nl; + for (i=0; account_policy_names[i].string; i++) { + memcpy(p, account_policy_names[i].string, strlen(account_policy_names[i].string) + 1); + p[strlen(account_policy_names[i].string)] = '\n'; + p += strlen(account_policy_names[i].string) + 1; + } + *p = '\0'; + return nl; +} + /**************************************************************************** Get the account policy name as a string from its #define'ed number ****************************************************************************/ @@ -111,9 +135,9 @@ int account_policy_name_to_fieldnum(const char *name) } - /**************************************************************************** ****************************************************************************/ + BOOL account_policy_get(int field, uint32 *value) { fstring name; @@ -159,4 +183,3 @@ BOOL account_policy_set(int field, uint32 value) return True; } - diff --git a/source3/passdb/passdb.c b/source3/passdb/passdb.c index 7e291ade22..ea1ce80442 100644 --- a/source3/passdb/passdb.c +++ b/source3/passdb/passdb.c @@ -932,7 +932,7 @@ BOOL local_password_change(const char *user_name, int local_flags, if ((local_flags & LOCAL_ADD_USER) || (local_flags & LOCAL_DELETE_USER)) { /* Might not exist in /etc/passwd. Use rid algorithm here */ if (!NT_STATUS_IS_OK(pdb_init_sam_new(&sam_pass, user_name, 0))) { - slprintf(err_str, err_str_len-1, "Failed to initialise SAM_ACCOUNT for user %s.\n", user_name); + slprintf(err_str, err_str_len-1, "Failed to initialise SAM_ACCOUNT for user %s. Does this user exist in the UNIX password database ?\n", user_name); return False; } } else { @@ -1840,12 +1840,27 @@ BOOL init_sam_from_buffer_v2(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen) /* Change from V1 is addition of password history field. */ account_policy_get(AP_PASSWORD_HISTORY, &pwHistLen); - - if (pwHistLen && nt_pw_hist_ptr && ((nt_pw_hist_len % NT_HASH_LEN) == 0)) { - if (!pdb_set_pw_history(sampass, nt_pw_hist_ptr, nt_pw_hist_len/NT_HASH_LEN, PDB_SET)) { + if (pwHistLen) { + char *pw_hist = malloc(pwHistLen * NT_HASH_LEN); + if (!pw_hist) { + ret = False; + goto done; + } + memset(pw_hist, '\0', pwHistLen * NT_HASH_LEN); + if (nt_pw_hist_ptr && nt_pw_hist_len) { + int i; + SMB_ASSERT((nt_pw_hist_len % NT_HASH_LEN) == 0); + nt_pw_hist_len /= NT_HASH_LEN; + for (i = 0; (i < pwHistLen) && (i < nt_pw_hist_len); i++) { + memcpy(&pw_hist[i*NT_HASH_LEN], &nt_pw_hist_ptr[i*NT_HASH_LEN], NT_HASH_LEN); + } + } + if (!pdb_set_pw_history(sampass, pw_hist, pwHistLen, PDB_SET)) { + SAFE_FREE(pw_hist); ret = False; goto done; } + SAFE_FREE(pw_hist); } else { pdb_set_pw_history(sampass, NULL, 0, PDB_SET); } diff --git a/source3/passdb/pdb_tdb.c b/source3/passdb/pdb_tdb.c index 97ef467064..5fb5ce3891 100644 --- a/source3/passdb/pdb_tdb.c +++ b/source3/passdb/pdb_tdb.c @@ -138,6 +138,9 @@ static BOOL tdbsam_convert(TDB_CONTEXT *pdb_tdb, tdbsamver_t from) return False; } + /* We're finished with the old data. */ + SAFE_FREE(data.dptr); + /* pack from the buffer into the new format */ DEBUG(10,("tdbsam_convert: Try packing a record (key:%s) (version:%d)\n", key.dptr, from)); if ((data.dsize=init_buffer_from_sam (&buf, user, False)) == -1) { diff --git a/source3/rpc_server/srv_pipe_hnd.c b/source3/rpc_server/srv_pipe_hnd.c index 7f7a3025a9..c0e6bf8f5e 100644 --- a/source3/rpc_server/srv_pipe_hnd.c +++ b/source3/rpc_server/srv_pipe_hnd.c @@ -1114,9 +1114,6 @@ static BOOL close_internal_rpc_pipe_hnd(void *np_conn) /* Free the handles database. */ close_policy_by_pipe(p); - if (p->session_key.data != NULL) - data_blob_free(&p->session_key); - delete_nt_token(&p->pipe_user.nt_user_token); data_blob_free(&p->session_key); SAFE_FREE(p->pipe_user.groups); diff --git a/source3/utils/pdbedit.c b/source3/utils/pdbedit.c index 3f7aba8366..06e9df22c2 100644 --- a/source3/utils/pdbedit.c +++ b/source3/utils/pdbedit.c @@ -736,7 +736,12 @@ int main (int argc, char **argv) uint32 value; int field = account_policy_name_to_fieldnum(account_policy); if (field == 0) { + char *apn = account_policy_names_list(); fprintf(stderr, "No account policy by that name\n"); + if (apn) { + fprintf(stderr, "Account policy names are :\n%s\n", apn); + } + SAFE_FREE(apn); exit(1); } if (!account_policy_get(field, &value)) { -- cgit