--- samba-4.2.1/source3/auth/auth_util.c.orig 2015-02-24 13:59:51.000000000 -0500 +++ samba-4.2.1/source3/auth/auth_util.c 2015-05-28 15:49:48.349595747 -0400 @@ -447,6 +447,8 @@ struct auth_session_info *session_info; struct unixid *ids; fstring tmp; + bool skip_token_from_info3; + struct unixid tmp_uid; /* Ensure we can't possible take a code path leading to a * null defref. */ @@ -535,11 +537,47 @@ /* * If winbind is not around, we can not make much use of the SIDs the * domain controller provided us with. Likewise if the user name was - * mapped to some local unix user. - */ + * mapped to some local unix user, EXCEPT in the case when the domain + * controller has a uidNumber mapping from the domain account to the + * correct local unix id, in which case we CAN use the SIDs provided + * by the domain controller. + * Previous behaviour was to always use create_token_from_username + * if the user name was mapped. This caused NT_STATUS_ACCESS_DENIED + * errors when trying to access a file owned by the local unix user + * if that userid gets mapped by winbind to a domain SID. So, we + * now only jump straight to create_token_from_username if winbind + * is unavailable or we have a mapped user and a non-domain-member + * role. For mapped users in a domain member role, we first try + * create_local_nt_token_from_info3 and then fall back to + * create_token_from_username if we don't get a satisfactory + * token with the right local unix id. + */ + if (((lp_server_role() == ROLE_DOMAIN_MEMBER) && !winbind_ping()) || - (server_info->nss_token)) { + (lp_server_role() != ROLE_DOMAIN_MEMBER && server_info->nss_token)) { + skip_token_from_info3 = true; + } else { + skip_token_from_info3 = false; + status = create_local_nt_token_from_info3(session_info, + server_info->guest, + server_info->info3, + &server_info->extra, + &session_info->security_token); + /* For a mapped user, skip the token we just obtained if + it doesn't have the right userid. */ + if (NT_STATUS_IS_OK(status) && server_info->nss_token) { + t = session_info->security_token; + if ((! sids_to_unixids(t->sids, 1, &tmp_uid)) || + (tmp_uid.type != ID_TYPE_UID) || + (tmp_uid.id != server_info->utok.uid)) { + skip_token_from_info3 = true; + } + } + + } + + if (skip_token_from_info3) { char *found_username = NULL; status = create_token_from_username(session_info, server_info->unix_name, @@ -551,12 +588,6 @@ if (NT_STATUS_IS_OK(status)) { session_info->unix_info->unix_name = found_username; } - } else { - status = create_local_nt_token_from_info3(session_info, - server_info->guest, - server_info->info3, - &server_info->extra, - &session_info->security_token); } if (!NT_STATUS_IS_OK(status)) {