source: n4d-netfolders/trunk/fuentes/install-files/usr/share/n4d/python-plugins/NetFoldersManager.py @ 4993

Last change on this file since 4993 was 4993, checked in by hectorgh, 3 years ago

fixing check_local_folders in slave

File size: 10.1 KB
Line 
1import os
2import os.path
3import shutil
4import json
5import re
6import subprocess
7import stat
8import grp
9import pwd
10import imp
11import threading
12sambaparser=imp.load_source("SambaParser","/usr/share/n4d/python-plugins/support/sambaparser.py")
13
14
15class NetFoldersManager:
16       
17       
18        LOCAL_CONF_FOLDER="/var/lib/lliurex-folders/local/"
19        SMB_CONF_FOLDER="/var/lib/lliurex-folders/smb/"
20        BASE_DIR="/net/server-sync/"
21       
22        def __init__(self):
23                       
24                self.debug=False       
25               
26                self.acl_thread=threading.Thread()
27               
28                if not os.path.exists(self.LOCAL_CONF_FOLDER):
29                        os.makedirs(self.LOCAL_CONF_FOLDER)
30                if not os.path.exists(self.SMB_CONF_FOLDER):
31                        os.makedirs(self.SMB_CONF_FOLDER)
32               
33        #def __init__
34       
35       
36        def startup(self,options):
37               
38                self.check_local_folders()
39                self.get_shared_folders()
40               
41        #def startup
42       
43        def backup(self,backup_target=None,backup_dest="/backup"):
44                if not backup_dest.endswith("/"):
45                        backup_dest+="/"
46                file_path=backup_dest+get_backup_name("NetFoldersManager")
47                if backup_target is None:
48                        backup_target = [os.path.join(self.BASE_DIR,x) for x in os.listdir(self.BASE_DIR)]
49                return objects['FileUtils'].backup(backup_target,file_path)
50
51        #def backup
52
53        def restore(self,backup_file=None):
54                if backup_file==None:
55                        for f in sorted(os.listdir("/backup"),reverse=True):
56                                if "NetFoldersManager" in f:
57                                        backup_file="/backup/"+f
58                                        break
59                return objects['FileUtils'].restore(backup_file,'/')
60
61        #def restore
62
63        def mount_gluster_volumes(self):
64                try:
65                        list_mount = []
66                        if not os.path.exists('/var/lib/n4d-glusterfs/volumes'):
67                                return True
68                        f = open('/var/lib/n4d-glusterfs/volumes')
69                        lines = f.readlines()
70                        to_mount = [ x[:x.find('#') - 1] for x in lines ]
71                        for x in range(1,10):
72                                mounted=objects['MountManager'].mount_list().keys()
73                                to_mount_b=[]
74                                for item in to_mount:
75                                        #to_mount_b.append(" ".join(item.split(" ")[0]))
76                                        to_mount_b.append(item.split(" ")[0])
77                                to_process=[]
78                                for item in to_mount_b:
79                                        if item not in mounted:
80                                                to_process.append(item)
81                                if len(to_process)==0:
82                                        break
83                                for item in to_mount:
84                                        for item2 in to_process:
85                                                if item.find(item2)!=-1:
86                                                        os.system("mount -t glusterfs -o acl " + item )
87                                                        continue
88                except Exception, e:
89                        pass
90                return True
91
92        #def mount_gluster_volumes
93
94
95        def get_acl_info(self,path):
96               
97                info={}
98                regex="(\w+:|\A)(user|group|mask|other):([a-zA-Z0-9\-]*):([r|w|x|\-]{1,3})\s*[#]*(\S+)*\Z"
99                os.environ["LANG"]="C"
100                p=subprocess.Popen(["getfacl","-n",path],stdout=subprocess.PIPE,stderr=subprocess.PIPE)
101                out=p.communicate()[0]
102               
103                info["acl"]=[]
104                info["perm"]=int(str(oct(stat.S_IMODE(os.lstat(path).st_mode))).lstrip("0"))
105                info["path"]=path
106               
107                for item in out.split("\n"):
108                       
109                        #item=item.strip("\n")
110                        x=re.match(regex,item)
111                       
112                        if x!=None:
113                               
114                                special=x.group(1)
115                                type_=x.group(2)
116                                custom_group=x.group(3)
117                                acl=x.group(4)
118                                extra=x.group(5)
119                               
120                                if special.find("default")!=-1:
121                                        mode="-d -m"
122                                else:
123                                        mode="-m"
124                                       
125                                if type_=="group":
126                                        type_="g:"
127                                elif type_=="user":
128                                        type_="u:"
129                                elif type_=="mask":
130                                        type_="m:"
131                                elif type_=="other":
132                                        type_="o:"
133                                       
134                               
135                                info["acl"].append([mode,type_+custom_group+":"+acl])
136                                       
137
138
139                return info
140               
141        #def get_acl_info
142       
143        def get_missing_acl_conf(self,info):
144               
145                ret=[]
146                ret_={}
147                for f in os.listdir(NetFoldersManager.LOCAL_CONF_FOLDER):
148                        try:
149                                ff=open(NetFoldersManager.LOCAL_CONF_FOLDER+f)
150                                txt="".join(ff.readlines())
151                                ff.close()
152                                orig_info=eval(txt)
153                                for item in orig_info:
154                                        found=False
155                                        if orig_info[item]["path"]==info["path"]:
156                                                for acl in orig_info[item]["acl"]:
157                                                        if not acl in info["acl"]:
158                                                                ret.append(acl)
159                                                        found=True
160                                                       
161                                                if found:
162                                               
163                                                        ret_[info["path"]]={}
164                                                        ret_[info["path"]]["path"]=info["path"]
165                                                        ret_[info["path"]]["perm"]=orig_info[item]["perm"]
166                                                        ret_[info["path"]]["acl"]=ret
167                                                               
168                                                        return(ret_)
169                       
170                       
171                               
172                        except Exception as e:
173                                print e
174                       
175                       
176                return None
177                       
178               
179        #def get_diferences
180       
181        def parse_local_folders_conf(self):
182               
183                for f in sorted(os.listdir(self.LOCAL_CONF_FOLDER)):
184                        try:
185                                #execfile(self.LOCAL_CONF_FOLDER+f)
186                                #self.local_dirs=dict(self.local_dirs.items()+locals()["folder"].items())
187                               
188                                f_=open(self.LOCAL_CONF_FOLDER+f,"r")
189                                data=json.load(f_)
190                                f_.close()                             
191                                self.local_dirs=dict(self.local_dirs.items()+data.items())
192                               
193                        except Exception as e:
194                                print("!!",e,"File: " + f)
195
196
197
198       
199        def check_local_folders(self,recursive=False):
200
201
202                if os.path.exists("/lib/systemd/system/net-server\\x2dsync.mount"):
203                        # Root has no access to /net/server-sync if it is mounted. Returning
204                        return True
205
206                self.local_dirs={}
207                #sorted!!!
208               
209                self.parse_local_folders_conf()
210               
211                #path,perm,acl
212               
213                for item in sorted(self.local_dirs.keys()):
214                       
215                        self.dprint("Checking %s configuration..."%item)
216                        path=self.local_dirs[item]["path"]
217                        try:
218                                user = int(self.local_dirs[item]["owner"])
219                        except:
220                                user = int(pwd.getpwnam(self.local_dirs[item]["owner"]).pw_uid)
221                        try:
222                                group = int(self.local_dirs[item]["group"])
223                        except:
224                                group = int(grp.getgrnam(self.local_dirs[item]["group"]).gr_gid)
225                        if not os.path.exists(path):
226                                print("\t* Creating path %s ..."%path)
227                                try:
228                                        os.makedirs(path)
229                                        prevmask=os.umask(0)
230                                        os.chmod(path,int(str(self.local_dirs[item]["perm"]),8))
231                                        os.lchown(path,user,group)
232                                        os.umask(prevmask)
233                                except Exception as e:
234                                        print("!!",e,path)
235
236
237
238                        try:                                   
239                                info=self.get_acl_info(path)
240                                info=self.get_missing_acl_conf(info)
241                               
242                                if ( os.lstat(path).st_uid != user ) or (os.lstat(path).st_gid != group):
243                                        os.lchown(path,user,group)
244                                if int(str(oct(stat.S_IMODE(os.lstat(path).st_mode))).lstrip("0"))!=info[path]["perm"]:
245                                        prevmask=os.umask(0)
246                                        os.chmod(path,int(str(info[path]["perm"]),8))
247                                        os.umask(prevmask)
248                               
249
250                                for acl in info[path]["acl"]:
251                                        print("\t* Setting acls to " + path + " ...")
252                                        options,value=acl
253                                        self.set_acl(path,options,value,recursive)
254                        except Exception as e:
255                                print e
256
257        #def check_local_folders
258       
259        def set_acl(self,path,options,value,recursive=False):
260               
261                if recursive:
262                        recursive="-R"
263                else:
264                        recursive=""
265       
266                if type(path)==type(""):
267                        path=path.decode("utf-8")
268               
269                cmd_str="setfacl %s %s %s '%s'"%(recursive,options,value,path)
270               
271                self.dprint(cmd_str)
272               
273                os.system(cmd_str.encode("utf-8"))
274                #here goes executing command
275               
276        #def set_acl
277       
278        def get_shared_folders(self):
279               
280                self.remote_dirs={}
281               
282                try:
283                        srv_ip=objects["VariablesManager"].get_variable("SRV_IP")
284                except:
285                        pass
286                       
287                if srv_ip!=None:
288                        sp=sambaparser.SambaParser()
289                        for item in os.listdir(self.SMB_CONF_FOLDER):
290                                f=self.SMB_CONF_FOLDER+item
291                                sp.read(f)
292                                for key in sp.conf:
293                                        if key!=None:
294                                                try:
295                                                        line="//"+srv_ip+"/"+key
296                                                        self.remote_dirs[line]={}
297                                                        self.remote_dirs[line]["dst"]=sp.conf[key]["mount_point"]
298                                                        self.remote_dirs[line]["fstype"]="cifs"
299                                                except Exception as e:
300                                                        #print e
301                                                        pass
302                                               
303                return self.remote_dirs
304               
305        #def check_shared_folders
306       
307       
308        def dprint(self,item):
309               
310                if self.debug:
311               
312                        try:
313                                print("[NetFoldersManager] " + str(item) )
314                        except:
315                                pass
316               
317        #def dprint
318
319        def get_acl_group_filtered(self,group):
320                result = []
321                path = self.LOCAL_CONF_FOLDER + os.path.sep + group.lower()
322                if os.path.exists(path):
323                        aux_file = open(path)
324                        list_acl = json.load(aux_file)
325                       
326                        for items in list_acl.values():
327                                for x in items['acl']:
328                                        if '-d' in x[0]:
329                                                x[0] = u'-m'
330                                                result.append(x)
331                        aux_file.close()
332                return result
333               
334               
335        def is_dir_workable(self,current_dir,banned_list):
336               
337                for dir in banned_list:
338                       
339                        if dir in current_dir:
340                               
341                                return False
342                               
343                               
344                return True
345               
346        #def is_dir_workable
347
348
349        def restore_acls(self):
350               
351                try:
352               
353                        self.local_folders={}
354                        self.local_dirs={}
355                        self.parse_local_folders_conf()
356                       
357                        dirs_to_process={}
358                       
359                        for item in self.local_dirs:
360                                dirs_to_process[self.local_dirs[item]["path"]]=""
361                               
362                       
363
364                        for item in self.local_dirs:
365                               
366                               
367                                        owner=self.local_dirs[item]["owner"]
368                                        group=self.local_dirs[item]["group"]
369                                        path=self.local_dirs[item]["path"]
370                                        perm=self.local_dirs[item]["perm"]
371                                        acls=self.local_dirs[item]["acl"]
372                                        file_acls=[]
373                                       
374                                        dirs_to_process.pop(path)
375                                       
376                                        for acl in acls:
377                                                options,value=acl
378                                                if "-d" not in options:
379                                                        file_acls.append(acl)
380                                                       
381                                        '''
382                                        print item
383                                        print "\t",owner,group,path,perm
384                                        print "\t",file_acls
385                                        '''
386                                       
387                                        for walk_item in os.walk(path):
388                                                dir,subdirs,files=walk_item
389                                               
390                                                if self.is_dir_workable(dir,dirs_to_process):
391                                                        #print dir
392                                                        #print "\t",files
393                                                        dir=dir.encode("utf-8") 
394                                                        cmd="setfacl -k -b '" + dir + "'"
395                                                        os.system(cmd)
396                                                       
397                                                        prevmask=os.umask(0)
398                                                        os.chmod(path,int(str(perm),8))
399                                                                                                       
400                                                        for f in files:
401                                                                for acl in file_acls:
402                                                                        options,value=acl
403                                                                        if type(f)==type(u""):
404                                                                                f=f.encode("utf-8")
405                                                                       
406                                                                        self.set_acl(dir+"/"+f,options,value)
407                                                                self.set_acl(dir+"/"+f,"-m","m:rw")
408                                                       
409                                                        for acl in acls:
410                                                                options,value=acl
411                                                                self.set_acl(dir,options,value)
412                                                               
413                                                        os.umask(prevmask)
414                                                       
415                                                       
416                        return [True,""]
417                       
418                       
419                except Exception as e:
420                       
421                        return [False,str(e)]
422               
423               
424        #def restore_acls
425       
426        def restore_acls_via_thread(self):
427               
428                if not self.acl_thread.is_alive():
429                       
430                        self.acl_thread=threading.Thread(target=self.restore_acls)
431                        self.daemon=True
432                        self.acl_thread.start()
433                       
434                       
435                return True
436               
437               
438        #def restore_acls_via_thread
439       
440        def is_acl_thread_alive(self):
441               
442                return self.acl_thread.is_alive()
443
444        #def is_acl_thread_alive
445
446        def restore_teacher_access(self,student):
447
448                folders=["/net/server-sync/home/students/%s/Desktop","/net/server-sync/home/students/%s/Documents"]
449                if pwd.getpwnam(student).pw_uid > 20000:
450
451                        print "Fixing %s ..."%student
452
453                        for folder in folders:
454
455                                os.system("chown %s:nogroup '%s'"%(student,folder%student))
456                                os.system("chmod 770 -R '%s'"%(folder%student))
457
458                        return True
459
460                else:
461                        return False
462
463
464        #def restore_teacher_access
465
466       
467#class NetFoldersManager
468
469if __name__=="__main__":
470       
471        nfm=NetFoldersManager()
472        #nfm.restore_acls()
Note: See TracBrowser for help on using the repository browser.