Remove fstring from map_username. Create a more sane interface than the called-parame...
[kai/samba.git] / source3 / smbd / share_access.c
index cee88bcf0b509ebdff239719055bf8fbd1161c8d..d00616b24eb98b30b3b18f93ca52db15931c26a3 100644 (file)
@@ -5,7 +5,7 @@
    
    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 2 of the License, or
+   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,
    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, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 #include "includes.h"
+#include "smbd/globals.h"
+#include "../libcli/security/security.h"
 
 /*
  * No prefix means direct username
@@ -28,9 +29,7 @@
  * + and & may be combined
  */
 
-extern userdom_struct current_user_info;
-
-static BOOL do_group_checks(const char **name, const char **pattern)
+static bool do_group_checks(const char **name, const char **pattern)
 {
        if ((*name)[0] == '@') {
                *pattern = "&+";
@@ -65,19 +64,19 @@ static BOOL do_group_checks(const char **name, const char **pattern)
        return False;
 }
 
-static BOOL token_contains_name(TALLOC_CTX *mem_ctx,
+static bool token_contains_name(TALLOC_CTX *mem_ctx,
                                const char *username,
+                               const char *domain,
                                const char *sharename,
-                               const struct nt_user_token *token,
+                               const struct security_token *token,
                                const char *name)
 {
        const char *prefix;
-       DOM_SID sid;
+       struct dom_sid sid;
        enum lsa_SidType type;
 
        if (username != NULL) {
-               name = talloc_sub_basic(mem_ctx, username,
-                                       current_user_info.domain, name);
+               name = talloc_sub_basic(mem_ctx, username, domain, name);
        }
        if (sharename != NULL) {
                name = talloc_string_sub(mem_ctx, name, "%S", sharename);
@@ -86,7 +85,7 @@ static BOOL token_contains_name(TALLOC_CTX *mem_ctx,
        if (name == NULL) {
                /* This is too security sensitive, better panic than return a
                 * result that might be interpreted in a wrong way. */
-               smb_panic("substitutions failed\n");
+               smb_panic("substitutions failed");
        }
        
        /* check to see is we already have a SID */
@@ -131,12 +130,14 @@ static BOOL token_contains_name(TALLOC_CTX *mem_ctx,
                        continue;
                }
                if (*prefix == '&') {
-                       if (user_in_netgroup(username, name)) {
-                               return True;
+                       if (username) {
+                               if (user_in_netgroup(mem_ctx, username, name)) {
+                                       return True;
+                               }
                        }
                        continue;
                }
-               smb_panic("got invalid prefix from do_groups_check\n");
+               smb_panic("got invalid prefix from do_groups_check");
        }
        return False;
 }
@@ -152,9 +153,10 @@ static BOOL token_contains_name(TALLOC_CTX *mem_ctx,
  * The other use is the netgroup check when using @group or &group.
  */
 
-BOOL token_contains_name_in_list(const char *username,
+bool token_contains_name_in_list(const char *username,
+                                const char *domain,
                                 const char *sharename,
-                                const struct nt_user_token *token,
+                                const struct security_token *token,
                                 const char **list)
 {
        TALLOC_CTX *mem_ctx;
@@ -164,11 +166,12 @@ BOOL token_contains_name_in_list(const char *username,
        }
 
        if ( (mem_ctx = talloc_new(NULL)) == NULL ) {
-               smb_panic("talloc_new failed\n");
+               smb_panic("talloc_new failed");
        }
 
        while (*list != NULL) {
-               if (token_contains_name(mem_ctx, username, sharename,token, *list)) {
+               if (token_contains_name(mem_ctx, username, domain, sharename,
+                                       token, *list)) {
                        TALLOC_FREE(mem_ctx);
                        return True;
                }
@@ -192,10 +195,12 @@ BOOL token_contains_name_in_list(const char *username,
  * The other use is the netgroup check when using @group or &group.
  */
 
-BOOL user_ok_token(const char *username, struct nt_user_token *token, int snum)
+bool user_ok_token(const char *username, const char *domain,
+                  const struct security_token *token, int snum)
 {
        if (lp_invalid_users(snum) != NULL) {
-               if (token_contains_name_in_list(username, lp_servicename(snum),
+               if (token_contains_name_in_list(username, domain,
+                                               lp_servicename(snum),
                                                token,
                                                lp_invalid_users(snum))) {
                        DEBUG(10, ("User %s in 'invalid users'\n", username));
@@ -204,7 +209,7 @@ BOOL user_ok_token(const char *username, struct nt_user_token *token, int snum)
        }
 
        if (lp_valid_users(snum) != NULL) {
-               if (!token_contains_name_in_list(username,
+               if (!token_contains_name_in_list(username, domain,
                                                 lp_servicename(snum), token,
                                                 lp_valid_users(snum))) {
                        DEBUG(10, ("User %s not in 'valid users'\n",
@@ -217,7 +222,12 @@ BOOL user_ok_token(const char *username, struct nt_user_token *token, int snum)
                const char *list[2];
                list[0] = lp_username(snum);
                list[1] = NULL;
-               if (!token_contains_name_in_list(NULL, lp_servicename(snum),
+               if ((list[0] == NULL) || (*list[0] == '\0')) {
+                       DEBUG(0, ("'only user = yes' and no 'username ='\n"));
+                       return False;
+               }
+               if (!token_contains_name_in_list(NULL, domain,
+                                                lp_servicename(snum),
                                                 token, list)) {
                        DEBUG(10, ("%s != 'username'\n", username));
                        return False;
@@ -244,13 +254,16 @@ BOOL user_ok_token(const char *username, struct nt_user_token *token, int snum)
  * The other use is the netgroup check when using @group or &group.
  */
 
-BOOL is_share_read_only_for_token(const char *username,
-                                 struct nt_user_token *token, int snum)
+bool is_share_read_only_for_token(const char *username,
+                                 const char *domain,
+                                 const struct security_token *token,
+                                 connection_struct *conn)
 {
-       BOOL result = lp_readonly(snum);
+       int snum = SNUM(conn);
+       bool result = conn->read_only;
 
        if (lp_readlist(snum) != NULL) {
-               if (token_contains_name_in_list(username,
+               if (token_contains_name_in_list(username, domain,
                                                lp_servicename(snum), token,
                                                lp_readlist(snum))) {
                        result = True;
@@ -258,7 +271,7 @@ BOOL is_share_read_only_for_token(const char *username,
        }
 
        if (lp_writelist(snum) != NULL) {
-               if (token_contains_name_in_list(username,
+               if (token_contains_name_in_list(username, domain,
                                                lp_servicename(snum), token,
                                                lp_writelist(snum))) {
                        result = False;