r23779: Change from v2 or later to v3 or later.
[samba.git] / source3 / smbd / dir.c
index 98356882aa42144b4efc8c21ef9f9b78dae56440..074fe6aed69b4802301a88d54e4f278a2daa546e 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,
@@ -879,14 +879,15 @@ static BOOL user_can_read_file(connection_struct *conn, char *name, SMB_STRUCT_S
        /* Pseudo-open the file (note - no fd's created). */
 
        if(S_ISDIR(pst->st_mode)) {
-                status = open_directory(conn, name, pst,
+                status = open_directory(conn, NULL, name, pst,
                        READ_CONTROL_ACCESS,
                        FILE_SHARE_READ|FILE_SHARE_WRITE,
                        FILE_OPEN,
                        0, /* no create options. */
+                       FILE_ATTRIBUTE_DIRECTORY,
                        NULL, &fsp);
        } else {
-               status = open_file_stat(conn, name, pst, &fsp);
+               status = open_file_stat(conn, NULL, name, pst, &fsp);
        }
 
        if (!NT_STATUS_IS_OK(status)) {
@@ -942,7 +943,7 @@ static BOOL user_can_write_file(connection_struct *conn, char *name, SMB_STRUCT_
        if(S_ISDIR(pst->st_mode)) {
                return True;
        } else {
-               status = open_file_ntcreate(conn, name, pst,
+               status = open_file_ntcreate(conn, NULL, name, pst,
                        FILE_WRITE_ATTRIBUTES,
                        FILE_SHARE_READ|FILE_SHARE_WRITE,
                        FILE_OPEN,
@@ -1016,6 +1017,7 @@ BOOL is_visible_file(connection_struct *conn, const char *dir_path, const char *
        }
 
        if (hide_unreadable || hide_unwriteable || hide_special) {
+               pstring link_target;
                char *entry = NULL;
 
                if (asprintf(&entry, "%s/%s", dir_path, name) == -1) {
@@ -1025,10 +1027,7 @@ BOOL is_visible_file(connection_struct *conn, const char *dir_path, const char *
                /* If it's a dfs symlink, ignore _hide xxxx_ options */
                if (lp_host_msdfs() &&
                                lp_msdfs_root(SNUM(conn)) &&
-                                       /* We get away with NULL talloc ctx here as
-                                          we're not interested in the link contents
-                                          so we have nothing to free. */
-                               is_msdfs_link(NULL, conn, entry, NULL, NULL, NULL)) {
+                               is_msdfs_link(conn, entry, link_target, NULL)) {
                        SAFE_FREE(entry);
                        return True;
                }
@@ -1278,3 +1277,42 @@ BOOL SearchDir(struct smb_Dir *dirp, const char *name, long *poffset)
        }
        return False;
 }
+
+/*****************************************************************
+ Is this directory empty ?
+*****************************************************************/
+
+NTSTATUS can_delete_directory(struct connection_struct *conn,
+                               const char *dirname)
+{
+       NTSTATUS status = NT_STATUS_OK;
+       long dirpos = 0;
+       const char *dname;
+       struct smb_Dir *dir_hnd = OpenDir(conn, dirname, NULL, 0);
+
+       if (!dir_hnd) {
+               return map_nt_error_from_unix(errno);
+       }
+
+       while ((dname = ReadDirName(dir_hnd,&dirpos))) {
+               SMB_STRUCT_STAT st;
+
+               /* Quick check for "." and ".." */
+               if (dname[0] == '.') {
+                       if (!dname[1] || (dname[1] == '.' && !dname[2])) {
+                               continue;
+                       }
+               }
+
+               if (!is_visible_file(conn, dirname, dname, &st, True)) {
+                       continue;
+               }
+
+               DEBUG(10,("can_delete_directory: got name %s - can't delete\n", dname ));
+               status = NT_STATUS_DIRECTORY_NOT_EMPTY;
+               break;
+       }
+       CloseDir(dir_hnd);
+
+       return status;
+}