summaryrefslogtreecommitdiffstats
path: root/python/samba/samba3/libsmb_samba_internal.py
blob: ef0b30d774bcb7a6bb46ce5d532218dfc47da193 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# Copyright (C) Volker Lendecke <vl@samba.org> 2020
#
# 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/>.

from samba.samba3.libsmb_samba_cwrapper import *
from samba.dcerpc import security

class Conn(LibsmbCConn):
    def deltree(self, path):
        if self.chkpath(path):
            for entry in self.list(path):
                self.deltree(path + "\\" + entry['name'])
            self.rmdir(path)
        else:
            self.unlink(path)

    SECINFO_DEFAULT_FLAGS = \
        security.SECINFO_OWNER | \
        security.SECINFO_GROUP | \
        security.SECINFO_DACL | \
        security.SECINFO_SACL

    def required_access_for_get_secinfo(self, secinfo):
        access = 0

        #
        # This is based on MS-FSA
        # 2.1.5.13 Server Requests a Query of Security Information
        #
        # Note that MS-SMB2 3.3.5.20.3 Handling SMB2_0_INFO_SECURITY
        # doesn't specify any extra checks
        #

        if secinfo & security.SECINFO_OWNER:
            access |= security.SEC_STD_READ_CONTROL
        if secinfo & security.SECINFO_GROUP:
            access |= security.SEC_STD_READ_CONTROL
        if secinfo & security.SECINFO_DACL:
            access |= security.SEC_STD_READ_CONTROL
        if secinfo & security.SECINFO_SACL:
            access |= security.SEC_FLAG_SYSTEM_SECURITY

        if secinfo & security.SECINFO_LABEL:
            access |= security.SEC_STD_READ_CONTROL

        return access

    def required_access_for_set_secinfo(self, secinfo):
        access = 0

        #
        # This is based on MS-FSA
        # 2.1.5.16 Server Requests Setting of Security Information
        # and additional constraints from
        # MS-SMB2 3.3.5.21.3 Handling SMB2_0_INFO_SECURITY
        #

        if secinfo & security.SECINFO_OWNER:
            access |= security.SEC_STD_WRITE_OWNER
        if secinfo & security.SECINFO_GROUP:
            access |= security.SEC_STD_WRITE_OWNER
        if secinfo & security.SECINFO_DACL:
            access |= security.SEC_STD_WRITE_DAC
        if secinfo & security.SECINFO_SACL:
            access |= security.SEC_FLAG_SYSTEM_SECURITY

        if secinfo & security.SECINFO_LABEL:
            access |= security.SEC_STD_WRITE_OWNER

        if secinfo & security.SECINFO_ATTRIBUTE:
            access |= security.SEC_STD_WRITE_DAC

        if secinfo & security.SECINFO_SCOPE:
            access |= security.SEC_FLAG_SYSTEM_SECURITY

        if secinfo & security.SECINFO_BACKUP:
            access |= security.SEC_STD_WRITE_OWNER
            access |= security.SEC_STD_WRITE_DAC
            access |= security.SEC_FLAG_SYSTEM_SECURITY

        return access

    def get_acl(self,
                filename,
                sinfo=None,
                access_mask=None):
        """Get security descriptor for file."""
        if sinfo is None:
            sinfo = self.SECINFO_DEFAULT_FLAGS
        if access_mask is None:
            access_mask = self.required_access_for_get_secinfo(sinfo)
        fnum = self.create(
            Name=filename,
            DesiredAccess=access_mask,
            ShareAccess=(FILE_SHARE_READ|FILE_SHARE_WRITE))
        try:
            sd = self.get_sd(fnum, sinfo)
        finally:
            self.close(fnum)
        return sd

    def set_acl(self,
                filename,
                sd,
                sinfo=None,
                access_mask=None):
        """Set security descriptor for file."""
        if sinfo is None:
            sinfo = self.SECINFO_DEFAULT_FLAGS
        if access_mask is None:
            access_mask = self.required_access_for_set_secinfo(sinfo)
        fnum = self.create(
            Name=filename,
            DesiredAccess=access_mask,
            ShareAccess=(FILE_SHARE_READ|FILE_SHARE_WRITE))
        try:
            self.set_sd(fnum, sd, sinfo)
        finally:
            self.close(fnum)