/src/samba/source3/smbd/share_access.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | Unix SMB/CIFS implementation. |
3 | | Check access based on valid users, read list and friends |
4 | | Copyright (C) Volker Lendecke 2005 |
5 | | |
6 | | This program is free software; you can redistribute it and/or modify |
7 | | it under the terms of the GNU General Public License as published by |
8 | | the Free Software Foundation; either version 3 of the License, or |
9 | | (at your option) any later version. |
10 | | |
11 | | This program is distributed in the hope that it will be useful, |
12 | | but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | | GNU General Public License for more details. |
15 | | |
16 | | You should have received a copy of the GNU General Public License |
17 | | along with this program. If not, see <http://www.gnu.org/licenses/>. |
18 | | */ |
19 | | |
20 | | #include "includes.h" |
21 | | #include "smbd/smbd.h" |
22 | | #include "smbd/globals.h" |
23 | | #include "../libcli/security/security.h" |
24 | | |
25 | | /* |
26 | | * Check whether a user is contained in the list provided. |
27 | | * |
28 | | * Please note that the user name and share names passed in here mainly for |
29 | | * the substitution routines that expand the parameter values, the decision |
30 | | * whether a user is in the list is done after a lookup_name on the expanded |
31 | | * parameter value, solely based on comparing the SIDs in token. |
32 | | * |
33 | | * The other use is the netgroup check when using @group or &group. |
34 | | */ |
35 | | |
36 | | bool token_contains_name_in_list(const char *username, |
37 | | const char *domain, |
38 | | const char *sharename, |
39 | | const struct security_token *token, |
40 | | const char **list, |
41 | | bool *match) |
42 | 0 | { |
43 | 0 | *match = false; |
44 | 0 | if (list == NULL) { |
45 | 0 | return true; |
46 | 0 | } |
47 | 0 | while (*list != NULL) { |
48 | 0 | TALLOC_CTX *frame = talloc_stackframe(); |
49 | 0 | bool ok; |
50 | |
|
51 | 0 | ok = token_contains_name(frame, username, domain, sharename, |
52 | 0 | token, *list, match); |
53 | 0 | TALLOC_FREE(frame); |
54 | 0 | if (!ok) { |
55 | 0 | return false; |
56 | 0 | } |
57 | 0 | if (*match) { |
58 | 0 | return true; |
59 | 0 | } |
60 | 0 | list += 1; |
61 | 0 | } |
62 | 0 | return true; |
63 | 0 | } |
64 | | |
65 | | /* |
66 | | * Check whether the user described by "token" has access to share snum. |
67 | | * |
68 | | * This looks at "invalid users" and "valid users". |
69 | | * |
70 | | * Please note that the user name and share names passed in here mainly for |
71 | | * the substitution routines that expand the parameter values, the decision |
72 | | * whether a user is in the list is done after a lookup_name on the expanded |
73 | | * parameter value, solely based on comparing the SIDs in token. |
74 | | * |
75 | | * The other use is the netgroup check when using @group or &group. |
76 | | */ |
77 | | |
78 | | bool user_ok_token(const char *username, const char *domain, |
79 | | const struct security_token *token, int snum) |
80 | 0 | { |
81 | 0 | const struct loadparm_substitution *lp_sub = |
82 | 0 | loadparm_s3_global_substitution(); |
83 | 0 | bool match; |
84 | 0 | bool ok; |
85 | |
|
86 | 0 | if (lp_invalid_users(snum) != NULL) { |
87 | 0 | ok = token_contains_name_in_list(username, domain, |
88 | 0 | lp_servicename(talloc_tos(), lp_sub, snum), |
89 | 0 | token, |
90 | 0 | lp_invalid_users(snum), |
91 | 0 | &match); |
92 | 0 | if (!ok) { |
93 | 0 | return false; |
94 | 0 | } |
95 | 0 | if (match) { |
96 | 0 | DEBUG(10, ("User %s in 'invalid users'\n", username)); |
97 | 0 | return False; |
98 | 0 | } |
99 | 0 | } |
100 | | |
101 | 0 | if (lp_valid_users(snum) != NULL) { |
102 | 0 | ok = token_contains_name_in_list(username, domain, |
103 | 0 | lp_servicename(talloc_tos(), lp_sub, snum), |
104 | 0 | token, |
105 | 0 | lp_valid_users(snum), |
106 | 0 | &match); |
107 | 0 | if (!ok) { |
108 | 0 | return false; |
109 | 0 | } |
110 | 0 | if (!match) { |
111 | 0 | DEBUG(10, ("User %s not in 'valid users'\n", |
112 | 0 | username)); |
113 | 0 | return False; |
114 | 0 | } |
115 | 0 | } |
116 | | |
117 | 0 | DEBUG(10, ("user_ok_token: share %s is ok for unix user %s\n", |
118 | 0 | lp_servicename(talloc_tos(), lp_sub, snum), username)); |
119 | |
|
120 | 0 | return True; |
121 | 0 | } |
122 | | |
123 | | /* |
124 | | * Check whether the user described by "token" is restricted to read-only |
125 | | * access on share snum. |
126 | | * |
127 | | * This looks at "read list", "write list" and "read only". |
128 | | * |
129 | | * Please note that the user name and share names passed in here mainly for |
130 | | * the substitution routines that expand the parameter values, the decision |
131 | | * whether a user is in the list is done after a lookup_name on the expanded |
132 | | * parameter value, solely based on comparing the SIDs in token. |
133 | | * |
134 | | * The other use is the netgroup check when using @group or &group. |
135 | | */ |
136 | | |
137 | | bool is_share_read_only_for_token(const char *username, |
138 | | const char *domain, |
139 | | const struct security_token *token, |
140 | | connection_struct *conn, |
141 | | bool *_read_only) |
142 | 0 | { |
143 | 0 | const struct loadparm_substitution *lp_sub = |
144 | 0 | loadparm_s3_global_substitution(); |
145 | 0 | int snum = SNUM(conn); |
146 | 0 | bool read_only = conn->read_only; |
147 | 0 | bool match; |
148 | 0 | bool ok; |
149 | |
|
150 | 0 | if (lp_read_list(snum) != NULL) { |
151 | 0 | ok = token_contains_name_in_list(username, domain, |
152 | 0 | lp_servicename(talloc_tos(), lp_sub, snum), |
153 | 0 | token, |
154 | 0 | lp_read_list(snum), |
155 | 0 | &match); |
156 | 0 | if (!ok) { |
157 | 0 | return false; |
158 | 0 | } |
159 | 0 | if (match) { |
160 | 0 | read_only = true; |
161 | 0 | } |
162 | 0 | } |
163 | | |
164 | 0 | if (lp_write_list(snum) != NULL) { |
165 | 0 | ok = token_contains_name_in_list(username, domain, |
166 | 0 | lp_servicename(talloc_tos(), lp_sub, snum), |
167 | 0 | token, |
168 | 0 | lp_write_list(snum), |
169 | 0 | &match); |
170 | 0 | if (!ok) { |
171 | 0 | return false; |
172 | 0 | } |
173 | 0 | if (match) { |
174 | 0 | read_only = false; |
175 | 0 | } |
176 | 0 | } |
177 | | |
178 | 0 | DEBUG(10,("is_share_read_only_for_user: share %s is %s for unix user " |
179 | 0 | "%s\n", lp_servicename(talloc_tos(), lp_sub, snum), |
180 | 0 | read_only ? "read-only" : "read-write", username)); |
181 | |
|
182 | 0 | *_read_only = read_only; |
183 | 0 | return true; |
184 | 0 | } |