diff options
author | Gerald Carter <jerry@samba.org> | 2004-08-06 05:44:26 +0000 |
---|---|---|
committer | Gerald Carter <jerry@samba.org> | 2004-08-06 05:44:26 +0000 |
commit | 547587d57c0ca7fa5babac358d4b2f67a472e142 (patch) | |
tree | abbcd3ba0d6ab0e15317fc0930a3c8e109f322f9 /source | |
parent | fecd5ea163ffcd1bbee5b06e05112dbff9aa71b1 (diff) | |
download | samba-3.0.6rc2.tar.gz samba-3.0.6rc2.tar.xz samba-3.0.6rc2.zip |
r1664: last changes before 3.0.6rc2samba-3.0.6rc2
Diffstat (limited to 'source')
-rwxr-xr-x | source/client/mount.cifs.c | 42 | ||||
-rw-r--r-- | source/include/smb.h | 5 | ||||
-rw-r--r-- | source/lib/snprintf.c | 2 | ||||
-rw-r--r-- | source/libsmb/smbencrypt.c | 20 | ||||
-rw-r--r-- | source/nsswitch/winbindd_group.c | 56 | ||||
-rw-r--r-- | source/nsswitch/winbindd_user.c | 8 | ||||
-rw-r--r-- | source/param/loadparm.c | 2 | ||||
-rw-r--r-- | source/passdb/passdb.c | 14 | ||||
-rw-r--r-- | source/passdb/pdb_get_set.c | 37 | ||||
-rw-r--r-- | source/smbd/chgpasswd.c | 20 |
10 files changed, 170 insertions, 36 deletions
diff --git a/source/client/mount.cifs.c b/source/client/mount.cifs.c index 5670a147468..55934e04b3c 100755 --- a/source/client/mount.cifs.c +++ b/source/client/mount.cifs.c @@ -38,7 +38,7 @@ #include <fcntl.h> #define MOUNT_CIFS_VERSION_MAJOR "1" -#define MOUNT_CIFS_VERSION_MINOR "3" +#define MOUNT_CIFS_VERSION_MINOR "4" #ifndef MOUNT_CIFS_VENDOR_SUFFIX #define MOUNT_CIFS_VENDOR_SUFFIX "" @@ -57,6 +57,7 @@ static int got_ip = 0; static int got_unc = 0; static int got_uid = 0; static int got_gid = 0; +static int free_share_name = 0; static char * user_name = NULL; char * mountpassword = NULL; @@ -502,8 +503,9 @@ static int parse_options(char * options, int * filesys_flags) } /* Note that caller frees the returned buffer if necessary */ -char * parse_server(char * unc_name) +char * parse_server(char ** punc_name) { + char * unc_name = *punc_name; int length = strnlen(unc_name,1024); char * share; char * ipaddress_string = NULL; @@ -527,11 +529,23 @@ char * parse_server(char * unc_name) return 0; } else { if(strncmp(unc_name,"//",2) && strncmp(unc_name,"\\\\",2)) { - printf("mount error: improperly formatted UNC name."); - printf(" %s does not begin with \\\\ or //\n",unc_name); - return 0; + /* check for nfs syntax ie server:share */ + share = strchr(unc_name,':'); + if(share) { + free_share_name = 1; + *punc_name = malloc(length+3); + *share = '/'; + strncpy((*punc_name)+2,unc_name,length); + unc_name = *punc_name; + unc_name[length+2] = 0; + goto continue_unc_parsing; + } else { + printf("mount error: improperly formatted UNC name."); + printf(" %s does not begin with \\\\ or //\n",unc_name); + return 0; + } } else { - unc_name[0] = '\\'; +continue_unc_parsing: unc_name[0] = '/'; unc_name[1] = '/'; unc_name += 2; @@ -753,8 +767,7 @@ int main(int argc, char ** argv) get_password_from_file(0, getenv("PASSWD_FILE")); } - ipaddr = parse_server(share_name); - + ipaddr = parse_server(&share_name); if(ipaddr == NULL) return -1; @@ -879,8 +892,9 @@ int main(int argc, char ** argv) mountent.mnt_fsname = share_name; mountent.mnt_dir = mountpoint; mountent.mnt_type = "cifs"; - mountent.mnt_opts = malloc(200); + mountent.mnt_opts = malloc(220); if(mountent.mnt_opts) { + char * mount_user = getusername(); memset(mountent.mnt_opts,0,200); if(flags & MS_RDONLY) strcat(mountent.mnt_opts,"ro"); @@ -898,6 +912,13 @@ int main(int argc, char ** argv) strcat(mountent.mnt_opts,",nodev"); if(flags & MS_SYNCHRONOUS) strcat(mountent.mnt_opts,",synch"); + if(mount_user) { + if(getuid() != 0) { + strcat(mountent.mnt_opts,",user="); + strcat(mountent.mnt_opts,mount_user); + } + free(mount_user); + } } mountent.mnt_freq = 0; mountent.mnt_passno = 0; @@ -927,6 +948,9 @@ int main(int argc, char ** argv) free(resolved_path); } + if(free_share_name) { + free(share_name); + } return 0; } diff --git a/source/include/smb.h b/source/include/smb.h index a802e962266..32dba0cf78f 100644 --- a/source/include/smb.h +++ b/source/include/smb.h @@ -625,6 +625,11 @@ typedef struct { #define NT_HASH_LEN 16 #define LM_HASH_LEN 16 +/* Password history contants. */ +#define PW_HISTORY_SALT_LEN 16 +#define SALTED_MD5_HASH_LEN 16 +#define PW_HISTORY_ENTRY_LEN (PW_HISTORY_SALT_LEN+SALTED_MD5_HASH_LEN) + /* * Flags for account policy. */ diff --git a/source/lib/snprintf.c b/source/lib/snprintf.c index 79de3c0ca5d..633517def28 100644 --- a/source/lib/snprintf.c +++ b/source/lib/snprintf.c @@ -821,6 +821,7 @@ static void dopr_outch(char *buffer, size_t *currlen, size_t maxlen, char c) { return dopr(str, count, fmt, args); } +#define vsnprintf smb_vsnprintf #endif /* yes this really must be a ||. Don't muck with this (tridge) @@ -840,6 +841,7 @@ int smb_snprintf(char *str,size_t count,const char *fmt,...) va_end(ap); return ret; } +#define snprintf smb_snprintf #endif #endif diff --git a/source/libsmb/smbencrypt.c b/source/libsmb/smbencrypt.c index 9f936b77aec..d4b05574118 100644 --- a/source/libsmb/smbencrypt.c +++ b/source/libsmb/smbencrypt.c @@ -73,6 +73,26 @@ void E_md4hash(const char *passwd, uchar p16[16]) } /** + * Creates the MD5 Hash of a combination of 16 byte salt and 16 byte NT hash. + * @param 16 byte salt. + * @param 16 byte NT hash. + * @param 16 byte return hashed with md5, caller allocated 16 byte buffer + */ + +void E_md5hash(const uchar salt[16], const uchar nthash[16], uchar hash_out[16]) +{ + struct MD5Context tctx; + uchar array[32]; + + memset(hash_out, '\0', 16); + memcpy(array, salt, 16); + memcpy(&array[16], nthash, 16); + MD5Init(&tctx); + MD5Update(&tctx, array, 32); + MD5Final(hash_out, &tctx); +} + +/** * Creates the DES forward-only Hash of the users password in DOS ASCII charset * @param passwd password in 'unix' charset. * @param p16 return password hashed with DES, caller allocated 16 byte buffer diff --git a/source/nsswitch/winbindd_group.c b/source/nsswitch/winbindd_group.c index 346a2711b6c..ca7f72d0178 100644 --- a/source/nsswitch/winbindd_group.c +++ b/source/nsswitch/winbindd_group.c @@ -1169,6 +1169,48 @@ enum winbindd_result winbindd_getgroups(struct winbindd_cli_state *state) return result; } +static void add_sid_to_array_unique(TALLOC_CTX *mem_ctx, const DOM_SID *sid, + DOM_SID ***sids, int *num_sids) +{ + int i; + + for (i=0; i<(*num_sids); i++) { + if (sid_compare(sid, (*sids)[i]) == 0) + return; + } + + *sids = talloc_realloc(mem_ctx, *sids, sizeof(**sids) * (*num_sids+1)); + + if (*sids == NULL) + return; + + (*sids)[*num_sids] = talloc(mem_ctx, sizeof(DOM_SID)); + sid_copy((*sids)[*num_sids], sid); + *num_sids += 1; + return; +} + +static void add_local_sids_from_sid(TALLOC_CTX *mem_ctx, const DOM_SID *sid, + DOM_SID ***user_grpsids, + int *num_groups) +{ + DOM_SID *aliases = NULL; + int i, num_aliases = 0; + + if (!pdb_enum_alias_memberships(sid, &aliases, &num_aliases)) + return; + + if (num_aliases == 0) + return; + + for (i=0; i<num_aliases; i++) + add_sid_to_array_unique(mem_ctx, &aliases[i], user_grpsids, + num_groups); + + SAFE_FREE(aliases); + + return; +} /* Get user supplementary sids. This is equivalent to the winbindd_getgroups() function but it involves a SID->SIDs mapping @@ -1224,6 +1266,20 @@ enum winbindd_result winbindd_getusersids(struct winbindd_cli_state *state) goto no_groups; } + if (lp_winbind_nested_groups()) { + int k; + /* num_groups is changed during the loop, that's why we have + to count down here.*/ + + for (k=num_groups-1; k>=0; k--) { + add_local_sids_from_sid(mem_ctx, user_grpsids[k], + &user_grpsids, &num_groups); + } + + add_local_sids_from_sid(mem_ctx, &user_sid, &user_grpsids, + &num_groups); + } + /* work out the response size */ for (i = 0; i < num_groups; i++) { const char *s = sid_string_static(user_grpsids[i]); diff --git a/source/nsswitch/winbindd_user.c b/source/nsswitch/winbindd_user.c index c691705f9c0..795d657aae7 100644 --- a/source/nsswitch/winbindd_user.c +++ b/source/nsswitch/winbindd_user.c @@ -46,14 +46,14 @@ static BOOL winbindd_fill_pwent(char *dom_name, char *user_name, /* Resolve the uid number */ - if (!NT_STATUS_IS_OK(idmap_sid_to_uid(user_sid, &(pw->pw_uid), 0))) { + if (!NT_STATUS_IS_OK(idmap_sid_to_uid(user_sid, &pw->pw_uid, 0))) { DEBUG(1, ("error getting user id for sid %s\n", sid_to_string(sid_string, user_sid))); return False; } /* Resolve the gid number */ - if (!NT_STATUS_IS_OK(idmap_sid_to_gid(group_sid, &(pw->pw_gid), 0))) { + if (!NT_STATUS_IS_OK(idmap_sid_to_gid(group_sid, &pw->pw_gid, 0))) { DEBUG(1, ("error getting group id for sid %s\n", sid_to_string(sid_string, group_sid))); return False; } @@ -185,7 +185,7 @@ enum winbindd_result winbindd_getpwnam(struct winbindd_cli_state *state) } /* Now take all this information and fill in a passwd structure */ - if (!winbindd_fill_pwent(name_domain, name_user, + if (!winbindd_fill_pwent(name_domain, user_info.acct_name, user_info.user_sid, user_info.group_sid, user_info.full_name, &state->response.data.pw)) { @@ -283,7 +283,7 @@ enum winbindd_result winbindd_getpwuid(struct winbindd_cli_state *state) /* Fill in password structure */ - if (!winbindd_fill_pwent(domain->name, user_name, user_info.user_sid, + if (!winbindd_fill_pwent(domain->name, user_info.acct_name, user_info.user_sid, user_info.group_sid, user_info.full_name, &state->response.data.pw)) { talloc_destroy(mem_ctx); diff --git a/source/param/loadparm.c b/source/param/loadparm.c index 978ea89d5c6..549e232fe07 100644 --- a/source/param/loadparm.c +++ b/source/param/loadparm.c @@ -1120,7 +1120,7 @@ static struct parm_struct parm_table[] = { {"remote browse sync", P_STRING, P_GLOBAL, &Globals.szRemoteBrowseSync, NULL, NULL, FLAG_ADVANCED}, {"socket address", P_STRING, P_GLOBAL, &Globals.szSocketAddress, NULL, NULL, FLAG_ADVANCED}, {"homedir map", P_STRING, P_GLOBAL, &Globals.szNISHomeMapName, NULL, NULL, FLAG_ADVANCED}, - {"afs username map", P_USTRING, P_GLOBAL, &Globals.szAfsUsernameMap, NULL, NULL, FLAG_ADVANCED}, + {"afs username map", P_STRING, P_GLOBAL, &Globals.szAfsUsernameMap, NULL, NULL, FLAG_ADVANCED}, {"time offset", P_INTEGER, P_GLOBAL, &extra_time_offset, NULL, NULL, FLAG_ADVANCED}, {"NIS homedir", P_BOOL, P_GLOBAL, &Globals.bNISHomeMap, NULL, NULL, FLAG_ADVANCED}, {"-valid", P_BOOL, P_LOCAL, &sDefault.valid, NULL, NULL, FLAG_HIDE}, diff --git a/source/passdb/passdb.c b/source/passdb/passdb.c index 2f9742e17da..e404f5af3f9 100644 --- a/source/passdb/passdb.c +++ b/source/passdb/passdb.c @@ -1841,18 +1841,20 @@ 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) { - char *pw_hist = malloc(pwHistLen * NT_HASH_LEN); + char *pw_hist = malloc(pwHistLen * PW_HISTORY_ENTRY_LEN); if (!pw_hist) { ret = False; goto done; } - memset(pw_hist, '\0', pwHistLen * NT_HASH_LEN); + memset(pw_hist, '\0', pwHistLen * PW_HISTORY_ENTRY_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; + SMB_ASSERT((nt_pw_hist_len % PW_HISTORY_ENTRY_LEN) == 0); + nt_pw_hist_len /= PW_HISTORY_ENTRY_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); + memcpy(&pw_hist[i*PW_HISTORY_ENTRY_LEN], + &nt_pw_hist_ptr[i*PW_HISTORY_ENTRY_LEN], + PW_HISTORY_ENTRY_LEN); } } if (!pdb_set_pw_history(sampass, pw_hist, pwHistLen, PDB_SET)) { @@ -2048,7 +2050,7 @@ uint32 init_buffer_from_sam_v2 (uint8 **buf, const SAM_ACCOUNT *sampass, BOOL si account_policy_get(AP_PASSWORD_HISTORY, &pwHistLen); nt_pw_hist = pdb_get_pw_history(sampass, &nt_pw_hist_len); if (pwHistLen && nt_pw_hist && nt_pw_hist_len) { - nt_pw_hist_len *= NT_HASH_LEN; + nt_pw_hist_len *= PW_HISTORY_ENTRY_LEN; } else { nt_pw_hist_len = 0; } diff --git a/source/passdb/pdb_get_set.c b/source/passdb/pdb_get_set.c index dc8a2f68d21..51c408e6d51 100644 --- a/source/passdb/pdb_get_set.c +++ b/source/passdb/pdb_get_set.c @@ -154,8 +154,8 @@ const uint8* pdb_get_pw_history (const SAM_ACCOUNT *sampass, uint32 *current_his { if (sampass) { SMB_ASSERT((!sampass->private.nt_pw_his.data) - || ((sampass->private.nt_pw_his.length % NT_HASH_LEN) == 0)); - *current_hist_len = sampass->private.nt_pw_his.length / NT_HASH_LEN; + || ((sampass->private.nt_pw_his.length % PW_HISTORY_ENTRY_LEN) == 0)); + *current_hist_len = sampass->private.nt_pw_his.length / PW_HISTORY_ENTRY_LEN; return ((uint8*)sampass->private.nt_pw_his.data); } else { *current_hist_len = 0; @@ -995,7 +995,8 @@ BOOL pdb_set_lanman_passwd (SAM_ACCOUNT *sampass, const uint8 pwd[LM_HASH_LEN], } /********************************************************************* - Set the user's password history hash. historyLen is the number of NT_HASH_LEN + Set the user's password history hash. historyLen is the number of + PW_HISTORY_SALT_LEN+SALTED_MD5_HASH_LEN length entries to store in the history - this must match the size of the uint8 array in pwd. ********************************************************************/ @@ -1006,7 +1007,8 @@ BOOL pdb_set_pw_history (SAM_ACCOUNT *sampass, const uint8 *pwd, uint32 historyL return False; if (historyLen && pwd){ - sampass->private.nt_pw_his = data_blob_talloc(sampass->mem_ctx, pwd, historyLen*NT_HASH_LEN); + sampass->private.nt_pw_his = data_blob_talloc(sampass->mem_ctx, + pwd, historyLen*PW_HISTORY_ENTRY_LEN); if (!sampass->private.nt_pw_his.length) { DEBUG(0, ("pdb_set_pw_history: data_blob_talloc() failed!\n")); return False; @@ -1221,17 +1223,34 @@ BOOL pdb_set_plaintext_passwd (SAM_ACCOUNT *sampass, const char *plaintext) have more history than we need. */ if (current_history_len < pwHistLen) { - /* We only have room for current_history_len entries. */ - pwHistLen = current_history_len; + /* Ensure we have space for the needed history. */ + uchar *new_history = talloc(sampass->mem_ctx, + pwHistLen*PW_HISTORY_ENTRY_LEN); + /* And copy it into the new buffer. */ + if (current_history_len) { + memcpy(new_history, pwhistory, + current_history_len*PW_HISTORY_ENTRY_LEN); + } + /* Clearing out any extra space. */ + memset(&new_history[current_history_len*PW_HISTORY_ENTRY_LEN], + '\0', (pwHistLen-current_history_len)*PW_HISTORY_ENTRY_LEN); + /* Finally replace it. */ + pwhistory = new_history; } } if (pwhistory && pwHistLen){ /* Make room for the new password in the history list. */ if (pwHistLen > 1) { - memmove(&pwhistory[NT_HASH_LEN], pwhistory, (pwHistLen -1)*NT_HASH_LEN ); + memmove(&pwhistory[PW_HISTORY_ENTRY_LEN], + pwhistory, (pwHistLen -1)*PW_HISTORY_ENTRY_LEN ); } - /* Ensure we have a copy of the new password as the first history entry. */ - memcpy(pwhistory, new_nt_p16, NT_HASH_LEN); + /* Create the new salt as the first part of the history entry. */ + generate_random_buffer(pwhistory, PW_HISTORY_SALT_LEN); + + /* Generate the md5 hash of the salt+new password as the second + part of the history entry. */ + + E_md5hash(pwhistory, new_nt_p16, &pwhistory[PW_HISTORY_SALT_LEN]); pdb_set_pw_history(sampass, pwhistory, pwHistLen, PDB_CHANGED); } else { DEBUG (10,("pdb_get_set.c: pdb_set_plaintext_passwd: pwhistory was NULL!\n")); diff --git a/source/smbd/chgpasswd.c b/source/smbd/chgpasswd.c index a1b90c8fed4..5c1d66abc44 100644 --- a/source/smbd/chgpasswd.c +++ b/source/smbd/chgpasswd.c @@ -941,7 +941,7 @@ static NTSTATUS check_oem_password(const char *user, static BOOL check_passwd_history(SAM_ACCOUNT *sampass, const char *plaintext) { uchar new_nt_p16[NT_HASH_LEN]; - uchar zero_nt_pw[NT_HASH_LEN]; + uchar zero_md5_nt_pw[SALTED_MD5_HASH_LEN]; const uint8 *nt_pw; const uint8 *pwhistory; BOOL found = False; @@ -972,22 +972,28 @@ static BOOL check_passwd_history(SAM_ACCOUNT *sampass, const char *plaintext) } dump_data(100, new_nt_p16, NT_HASH_LEN); - dump_data(100, pwhistory, NT_HASH_LEN*pwHisLen); + dump_data(100, pwhistory, PW_HISTORY_ENTRY_LEN*pwHisLen); - memset(zero_nt_pw, '\0', NT_HASH_LEN); + memset(zero_md5_nt_pw, '\0', SALTED_MD5_HASH_LEN); for (i=0; i<pwHisLen; i++) { - if (!memcmp(&pwhistory[i*NT_HASH_LEN], zero_nt_pw, NT_HASH_LEN)) { - /* Ignore zero entries. */ + uchar new_nt_pw_salted_md5_hash[SALTED_MD5_HASH_LEN]; + const uchar *current_salt = &pwhistory[i*PW_HISTORY_ENTRY_LEN]; + const uchar *old_nt_pw_salted_md5_hash = &pwhistory[(i*PW_HISTORY_ENTRY_LEN)+ + PW_HISTORY_SALT_LEN]; + if (!memcmp(zero_md5_nt_pw, old_nt_pw_salted_md5_hash, SALTED_MD5_HASH_LEN)) { + /* Ignore zero valued entries. */ continue; } - if (!memcmp(&pwhistory[i*NT_HASH_LEN], new_nt_p16, NT_HASH_LEN)) { + /* Create salted versions of new to compare. */ + E_md5hash(current_salt, new_nt_p16, new_nt_pw_salted_md5_hash); + + if (!memcmp(new_nt_pw_salted_md5_hash, old_nt_pw_salted_md5_hash, SALTED_MD5_HASH_LEN)) { DEBUG(1,("check_passwd_history: proposed new password for user %s found in history list !\n", pdb_get_username(sampass) )); found = True; break; } } - return found; } |