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

Last change on this file since 177 was 177, checked in by hectorgh, 5 years ago

adding project files

File size: 10.0 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                self.mount_gluster_volumes()
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                self.local_dirs={}
202                #sorted!!!
203               
204                self.parse_local_folders_conf()
205               
206                #path,perm,acl
207               
208                for item in sorted(self.local_dirs.keys()):
209                       
210                        self.dprint("Checking %s configuration..."%item)
211                        path=self.local_dirs[item]["path"]
212                        try:
213                                user = int(self.local_dirs[item]["owner"])
214                        except:
215                                user = int(pwd.getpwnam(self.local_dirs[item]["owner"]).pw_uid)
216                        try:
217                                group = int(self.local_dirs[item]["group"])
218                        except:
219                                group = int(grp.getgrnam(self.local_dirs[item]["group"]).gr_gid)
220                        if not os.path.exists(path):
221                                print("\t* Creating path %s ..."%path)
222                                try:
223                                        os.makedirs(path)
224                                        prevmask=os.umask(0)
225                                        os.chmod(path,int(str(self.local_dirs[item]["perm"]),8))
226                                        os.lchown(path,user,group)
227                                        os.umask(prevmask)
228                                except Exception as e:
229                                        print("!!",e,path)
230
231
232
233                        try:                                   
234                                info=self.get_acl_info(path)
235                                info=self.get_missing_acl_conf(info)
236                               
237                                if ( os.lstat(path).st_uid != user ) or (os.lstat(path).st_gid != group):
238                                        os.lchown(path,user,group)
239                                if int(str(oct(stat.S_IMODE(os.lstat(path).st_mode))).lstrip("0"))!=info[path]["perm"]:
240                                        prevmask=os.umask(0)
241                                        os.chmod(path,int(str(info[path]["perm"]),8))
242                                        os.umask(prevmask)
243                               
244
245                                for acl in info[path]["acl"]:
246                                        print("\t* Setting acls to " + path + " ...")
247                                        options,value=acl
248                                        self.set_acl(path,options,value,recursive)
249                        except Exception as e:
250                                print e
251
252        #def check_local_folders
253       
254        def set_acl(self,path,options,value,recursive=False):
255               
256                if recursive:
257                        recursive="-R"
258                else:
259                        recursive=""
260       
261                if type(path)==type(""):
262                        path=path.decode("utf-8")
263               
264                cmd_str="setfacl %s %s %s '%s'"%(recursive,options,value,path)
265               
266                self.dprint(cmd_str)
267               
268                os.system(cmd_str.encode("utf-8"))
269                #here goes executing command
270               
271        #def set_acl
272       
273        def get_shared_folders(self):
274               
275                self.remote_dirs={}
276               
277                try:
278                        srv_ip=objects["VariablesManager"].get_variable("SRV_IP")
279                except:
280                        pass
281                       
282                if srv_ip!=None:
283                        sp=sambaparser.SambaParser()
284                        for item in os.listdir(self.SMB_CONF_FOLDER):
285                                f=self.SMB_CONF_FOLDER+item
286                                sp.read(f)
287                                for key in sp.conf:
288                                        if key!=None:
289                                                try:
290                                                        line="//"+srv_ip+"/"+key
291                                                        self.remote_dirs[line]={}
292                                                        self.remote_dirs[line]["dst"]=sp.conf[key]["mount_point"]
293                                                        self.remote_dirs[line]["fstype"]="cifs"
294                                                except Exception as e:
295                                                        #print e
296                                                        pass
297                                               
298                return self.remote_dirs
299               
300        #def check_shared_folders
301       
302       
303        def dprint(self,item):
304               
305                if self.debug:
306               
307                        try:
308                                print("[NetFoldersManager] " + str(item) )
309                        except:
310                                pass
311               
312        #def dprint
313
314        def get_acl_group_filtered(self,group):
315                result = []
316                path = self.LOCAL_CONF_FOLDER + os.path.sep + group.lower()
317                if os.path.exists(path):
318                        aux_file = open(path)
319                        list_acl = json.load(aux_file)
320                       
321                        for items in list_acl.values():
322                                for x in items['acl']:
323                                        if '-d' in x[0]:
324                                                x[0] = u'-m'
325                                                result.append(x)
326                        aux_file.close()
327                return result
328               
329               
330        def is_dir_workable(self,current_dir,banned_list):
331               
332                for dir in banned_list:
333                       
334                        if dir in current_dir:
335                               
336                                return False
337                               
338                               
339                return True
340               
341        #def is_dir_workable
342
343
344        def restore_acls(self):
345               
346                try:
347               
348                        self.local_folders={}
349                        self.local_dirs={}
350                        self.parse_local_folders_conf()
351                       
352                        dirs_to_process={}
353                       
354                        for item in self.local_dirs:
355                                dirs_to_process[self.local_dirs[item]["path"]]=""
356                               
357                       
358
359                        for item in self.local_dirs:
360                               
361                               
362                                        owner=self.local_dirs[item]["owner"]
363                                        group=self.local_dirs[item]["group"]
364                                        path=self.local_dirs[item]["path"]
365                                        perm=self.local_dirs[item]["perm"]
366                                        acls=self.local_dirs[item]["acl"]
367                                        file_acls=[]
368                                       
369                                        dirs_to_process.pop(path)
370                                       
371                                        for acl in acls:
372                                                options,value=acl
373                                                if "-d" not in options:
374                                                        file_acls.append(acl)
375                                                       
376                                        '''
377                                        print item
378                                        print "\t",owner,group,path,perm
379                                        print "\t",file_acls
380                                        '''
381                                       
382                                        for walk_item in os.walk(path):
383                                                dir,subdirs,files=walk_item
384                                               
385                                                if self.is_dir_workable(dir,dirs_to_process):
386                                                        #print dir
387                                                        #print "\t",files
388                                                        dir=dir.encode("utf-8") 
389                                                        cmd="setfacl -k -b '" + dir + "'"
390                                                        os.system(cmd)
391                                                       
392                                                        prevmask=os.umask(0)
393                                                        os.chmod(path,int(str(perm),8))
394                                                                                                       
395                                                        for f in files:
396                                                                for acl in file_acls:
397                                                                        options,value=acl
398                                                                        if type(f)==type(u""):
399                                                                                f=f.encode("utf-8")
400                                                                       
401                                                                        self.set_acl(dir+"/"+f,options,value)
402                                                                self.set_acl(dir+"/"+f,"-m","m:rw")
403                                                       
404                                                        for acl in acls:
405                                                                options,value=acl
406                                                                self.set_acl(dir,options,value)
407                                                               
408                                                        os.umask(prevmask)
409                                                       
410                                                       
411                        return [True,""]
412                       
413                       
414                except Exception as e:
415                       
416                        return [False,str(e)]
417               
418               
419        #def restore_acls
420       
421        def restore_acls_via_thread(self):
422               
423                if not self.acl_thread.is_alive():
424                       
425                        self.acl_thread=threading.Thread(target=self.restore_acls)
426                        self.daemon=True
427                        self.acl_thread.start()
428                       
429                       
430                return True
431               
432               
433        #def restore_acls_via_thread
434       
435        def is_acl_thread_alive(self):
436               
437                return self.acl_thread.is_alive()
438
439        #def is_acl_thread_alive
440
441        def restore_teacher_access(self,student):
442
443                folders=["/net/server-sync/home/students/%s/Desktop","/net/server-sync/home/students/%s/Documents"]
444                if pwd.getpwnam(student).pw_uid > 20000:
445
446                        print "Fixing %s ..."%student
447
448                        for folder in folders:
449
450                                os.system("chown %s:nogroup '%s'"%(student,folder%student))
451                                os.system("chmod 770 -R '%s'"%(folder%student))
452
453                        return True
454
455                else:
456                        return False
457
458
459        #def restore_teacher_access
460
461       
462#class NetFoldersManager
463
464if __name__=="__main__":
465       
466        nfm=NetFoldersManager()
467        #nfm.restore_acls()
Note: See TracBrowser for help on using the repository browser.