mirror of
https://github.com/samba-team/samba.git
synced 2024-12-23 17:34:34 +03:00
02ae847b45
Invalid names in "valid users", "invalid users", "read list", "write list", "veto files" and "hide files" are logged and ignored, but a failure to contact winbind or a DC from winbind, or a memory allocation failure, now all trigger a failure of the tree connect. Manually tested with smbclient with the following hack in winbindd: ---8<--- $ git di source3/winbindd/winbindd_cache.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/source3/winbindd/winbindd_cache.c b/source3/winbindd/winbindd_cache.c index c889489dbbbc..8ccf0a28e11a 100644 --- a/source3/winbindd/winbindd_cache.c +++ b/source3/winbindd/winbindd_cache.c @@ -1821,6 +1821,13 @@ NTSTATUS wb_cache_name_to_sid(struct winbindd_domain *domain, ZERO_STRUCTP(sid); *type = SID_NAME_UNKNOWN; + if (strequal(name, "unknown")) { + return NT_STATUS_OK; + } + if (strequal(name, "iotimeout")) { + return NT_STATUS_IO_TIMEOUT; + } + status = wcache_name_to_sid(domain, domain_name, name, sid, type); if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) { return status; ---8<--- veto files = ../unknown/file1/../slow/file2 $ bin/smbclient -U slow%x //localhost/test -c quit $ In the log: [2024/03/04 15:21:33.659356, 1, pid=977167, effective(0, 0), real(0, 0)] ../../source3/lib/util_namearray.c:128(token_contains_name) token_contains_name: lookup_name 'unknown' failed veto files = ../iotimeout/file1/../slow/file2 $ bin/smbclient -U slow%x //localhost/test -c quit tree connect failed: NT_STATUS_LOGON_FAILURE $ [2024/03/04 15:22:15.655811, 0, pid=977177, effective(0, 0), real(0, 0)] ../../source3/lib/util_namearray.c:131(token_contains_name) token_contains_name: lookup_name 'iotimeout' failed NT_STATUS_NO_SUCH_DOMAIN [2024/03/04 15:22:15.655846, 1, pid=977177, effective(0, 0), real(0, 0)] ../../source3/smbd/uid.c:381(change_to_user_impersonate) change_to_user_impersonate: SMB user slow (unix user slow) not permitted access to share test. [2024/03/04 15:22:15.655855, 0, pid=977177, effective(0, 0), real(0, 0)] ../../source3/smbd/smb2_service.c:689(make_connection_snum) make_connection_snum: Can't become connected user! Signed-off-by: Ralph Boehme <slow@samba.org> Reviewed-by: Stefan Metzmacher <metze@samba.org>
185 lines
5.0 KiB
C
185 lines
5.0 KiB
C
/*
|
|
Unix SMB/CIFS implementation.
|
|
Check access based on valid users, read list and friends
|
|
Copyright (C) Volker Lendecke 2005
|
|
|
|
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
|
|
the Free Software Foundation; either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include "includes.h"
|
|
#include "smbd/smbd.h"
|
|
#include "smbd/globals.h"
|
|
#include "../libcli/security/security.h"
|
|
|
|
/*
|
|
* Check whether a user is contained in the list provided.
|
|
*
|
|
* Please note that the user name and share names passed in here mainly for
|
|
* the substitution routines that expand the parameter values, the decision
|
|
* whether a user is in the list is done after a lookup_name on the expanded
|
|
* parameter value, solely based on comparing the SIDs in token.
|
|
*
|
|
* The other use is the netgroup check when using @group or &group.
|
|
*/
|
|
|
|
bool token_contains_name_in_list(const char *username,
|
|
const char *domain,
|
|
const char *sharename,
|
|
const struct security_token *token,
|
|
const char **list,
|
|
bool *match)
|
|
{
|
|
*match = false;
|
|
if (list == NULL) {
|
|
return true;
|
|
}
|
|
while (*list != NULL) {
|
|
TALLOC_CTX *frame = talloc_stackframe();
|
|
bool ok;
|
|
|
|
ok = token_contains_name(frame, username, domain, sharename,
|
|
token, *list, match);
|
|
TALLOC_FREE(frame);
|
|
if (!ok) {
|
|
return false;
|
|
}
|
|
if (*match) {
|
|
return true;
|
|
}
|
|
list += 1;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/*
|
|
* Check whether the user described by "token" has access to share snum.
|
|
*
|
|
* This looks at "invalid users" and "valid users".
|
|
*
|
|
* Please note that the user name and share names passed in here mainly for
|
|
* the substitution routines that expand the parameter values, the decision
|
|
* whether a user is in the list is done after a lookup_name on the expanded
|
|
* parameter value, solely based on comparing the SIDs in token.
|
|
*
|
|
* The other use is the netgroup check when using @group or &group.
|
|
*/
|
|
|
|
bool user_ok_token(const char *username, const char *domain,
|
|
const struct security_token *token, int snum)
|
|
{
|
|
const struct loadparm_substitution *lp_sub =
|
|
loadparm_s3_global_substitution();
|
|
bool match;
|
|
bool ok;
|
|
|
|
if (lp_invalid_users(snum) != NULL) {
|
|
ok = token_contains_name_in_list(username, domain,
|
|
lp_servicename(talloc_tos(), lp_sub, snum),
|
|
token,
|
|
lp_invalid_users(snum),
|
|
&match);
|
|
if (!ok) {
|
|
return false;
|
|
}
|
|
if (match) {
|
|
DEBUG(10, ("User %s in 'invalid users'\n", username));
|
|
return False;
|
|
}
|
|
}
|
|
|
|
if (lp_valid_users(snum) != NULL) {
|
|
ok = token_contains_name_in_list(username, domain,
|
|
lp_servicename(talloc_tos(), lp_sub, snum),
|
|
token,
|
|
lp_valid_users(snum),
|
|
&match);
|
|
if (!ok) {
|
|
return false;
|
|
}
|
|
if (!match) {
|
|
DEBUG(10, ("User %s not in 'valid users'\n",
|
|
username));
|
|
return False;
|
|
}
|
|
}
|
|
|
|
DEBUG(10, ("user_ok_token: share %s is ok for unix user %s\n",
|
|
lp_servicename(talloc_tos(), lp_sub, snum), username));
|
|
|
|
return True;
|
|
}
|
|
|
|
/*
|
|
* Check whether the user described by "token" is restricted to read-only
|
|
* access on share snum.
|
|
*
|
|
* This looks at "read list", "write list" and "read only".
|
|
*
|
|
* Please note that the user name and share names passed in here mainly for
|
|
* the substitution routines that expand the parameter values, the decision
|
|
* whether a user is in the list is done after a lookup_name on the expanded
|
|
* parameter value, solely based on comparing the SIDs in token.
|
|
*
|
|
* The other use is the netgroup check when using @group or &group.
|
|
*/
|
|
|
|
bool is_share_read_only_for_token(const char *username,
|
|
const char *domain,
|
|
const struct security_token *token,
|
|
connection_struct *conn,
|
|
bool *_read_only)
|
|
{
|
|
const struct loadparm_substitution *lp_sub =
|
|
loadparm_s3_global_substitution();
|
|
int snum = SNUM(conn);
|
|
bool read_only = conn->read_only;
|
|
bool match;
|
|
bool ok;
|
|
|
|
if (lp_read_list(snum) != NULL) {
|
|
ok = token_contains_name_in_list(username, domain,
|
|
lp_servicename(talloc_tos(), lp_sub, snum),
|
|
token,
|
|
lp_read_list(snum),
|
|
&match);
|
|
if (!ok) {
|
|
return false;
|
|
}
|
|
if (match) {
|
|
read_only = true;
|
|
}
|
|
}
|
|
|
|
if (lp_write_list(snum) != NULL) {
|
|
ok = token_contains_name_in_list(username, domain,
|
|
lp_servicename(talloc_tos(), lp_sub, snum),
|
|
token,
|
|
lp_write_list(snum),
|
|
&match);
|
|
if (!ok) {
|
|
return false;
|
|
}
|
|
if (match) {
|
|
read_only = false;
|
|
}
|
|
}
|
|
|
|
DEBUG(10,("is_share_read_only_for_user: share %s is %s for unix user "
|
|
"%s\n", lp_servicename(talloc_tos(), lp_sub, snum),
|
|
read_only ? "read-only" : "read-write", username));
|
|
|
|
*_read_only = read_only;
|
|
return true;
|
|
}
|