def on_user_change(user, data): username = user.username new_password = data.get('password', None) ftp_user, created = Users.objects.get_or_create(username=username) proftpd = Proftpd() if created: ftp_user.homedir = os.path.join(proftpd.config["DefaultRoot"][0], \ username.replace(" ", "_")) try: os.mkdir(ftp_user.homedir) os.chown(ftp_user.homedir, PROFTPD_UID, PROFTPD_GID) # Changing owner except OSError: log(5, "proftpd_app - event:on_user_change", "Failed to create directory or alter its owner") # Changing users's password if new_password: ftp_user.password = crypt.crypt(new_password, new_password) ftp_user.save() # Updating directory permissions if "ftp_client" in user.merged_permissions()["proftpd"]: proftpd.update_config() # Recreating groups ftp_groups = Groups.objects.filter(username=username) ftp_groups.delete() for group in user.groups.all(): Groups.objects.create(groupname=group.name, username=username) return 1
def on_user_create(new_user): print "on_user_create" permissions = new_user.merged_permissions() # If the user has "FTP client" rights then create an FTP user if "ftp_client" in permissions["proftpd"]: username, password = new_user.username, new_user.password proftpd = Proftpd(new_user) # We don't like spaces in directory names, so replace them with underscores homedir = os.path.join(proftpd.config["DefaultRoot"][0], \ username.replace(" ", "_")) # Create FTP user ftp_user = Users.objects.create(username=username, password=crypt.crypt(password, password), homedir=homedir) # Creating a home directory if not (os.path.exists(homedir) and os.path.isdir(homedir)): os.mkdir(homedir) # Changing the owner try: os.chown(homedir, PROFTPD_UID, PROFTPD_GID) except OSError, (errno, sterror): log(3, "proftpd_app - event:on_user_create", "OS error(%s): %s" % (errno, sterror)) # Creating user groups for group in new_user.groups.all(): Groups.objects.create(groupname=group.name, username=username) proftpd.update_config()
def on_group_delete(user, group): # Deleting all FTP groups associated with the group groups = Groups.objects.filter(groupname=group.name) groups.delete() # Fetching ProFTPD config on behalf of the user who is deleting the group proftpd = Proftpd(user) config = proftpd.config config.remove(["<Directory>", "*", "<Limit>", "*"], "AllowGroup", [group.name]) # Deleting the groups's instances from DB permissions for dir in FTP_DB: dir_perm = dict(FTP_DB[dir]) if "group" in dir_perm and group.name in dir_perm["group"]: del dir_perm["group"][group.name] FTP_DB[dir] = dir_perm FTP_DB.save() proftpd.update_config() return 1
def dashboard(request, mode): proftpd = Proftpd(request.user) return render_to_response("proftpd/dashboard.django.html", {"status": proftpd.connections(), "daemon": proftpd.status, "space": fs_space()[FTP_FS_PATH] }, context_instance=RequestContext(request))
def on_user_delete(user, victim): mode = user.merged_permissions()['accounts']['actions']['mode'] username = victim.username groups = Groups.objects.filter(username=username) groups.delete() try: ftp_user = Users.objects.get(username=username) except: log(1, "proftpd_app - event:on_user_delete", "No user with username '%s' has been found" % username) return 1 homedir = ftp_user.homedir # Gonna make changes to the config proftpd = Proftpd(user) config = proftpd.config # Deleting the user from permission instances in the config permissions = victim.merged_permissions() if "ftp_client" in permissions["proftpd"]: users = Users.objects.exclude(username='******') homedirs = [] [homedirs.append(user.homedir) for user in users] config.remove(["<Directory>", homedirs, "<Limit>", "*"], "AllowUser", [username]) # Deleting <Directory> instance from config path = proftpd.path() for p in path.ftp_dir_generator("/"+username, childs_only=True): config.drop(["<Directory>"], [p]) if p in FTP_DB: del FTP_DB[FTP_DB[p]] # Deleting the user's instances from DB permissions for dir in FTP_DB: dir_perm = dict(FTP_DB[dir]) if "user" in dir_perm and username in dir_perm["user"]: del dir_perm["user"][username] FTP_DB[dir] = dir_perm FTP_DB.save() # Deleting the directory itself try: shutil.rmtree(homedir) except: log(3, "proftpd_app - event:on_user_delete", "Failed to delete user's directory") if ftp_user: ftp_user.delete() # Reconfiguring... if not proftpd.update_config(): log(3, "proftpd_app - event:on_user_delete", "Failed to delete 'Directory' instance from the configuration file") return 1
def user_info(user, victim): try: ftp_user = Users.objects.get(username=victim.username) except Users.DoesNotExist: return "" path = Proftpd(victim).path("/%s" % victim.username) path.path_is_valid() info = path.info() # We should inform only if the user has a non-empty directory if "size" in info and info["size"]: return _("User %(username)s has an ftp directory with size of %(size)s bytes") % {"username": victim.username, "size": info["size"]} else: return ""
def on_group_change(user, group, old_data): if "ftp_client" in group.permissions["proftpd"]: mode = group.permissions["proftpd"]["ftp_client"]["access"] else: mode = None # Gonna make changes to the config proftpd = Proftpd(user) config = proftpd.config group_usernames = map(lambda x: x.username, old_data["users"]) all_ftp_users = Users.objects.exclude(username='******') homedirs = [] [homedirs.append(u.homedir) for u in all_ftp_users] config.remove(["<Directory>", homedirs, "<Limit>", "*"], "AllowUser", group_usernames) config.remove(["<Directory>", homedirs, "<Limit>", "*"], "AllowGroup", [group.name]) proftpd.update_config() return 1
def status(request, mode): proftpd = Proftpd(request.user) if request.method == "GET": return render_to_response("proftpd/status.django.html", {"status": proftpd.connections(), "daemon": proftpd.status, "space": fs_space()[FTP_FS_PATH] }, context_instance=RequestContext(request)) else: # POST ajax request status = proftpd.connections() template = get_template("proftpd/status_aux.django.html") connections = {} for user in status["users"]: connections[user] = template.render(Context({"conns": status["users"][user]})) template = get_template("proftpd/status_ajax.django.html") content = template.render(Context({"users": connections})) return HttpResponse(json.dumps({"total": status["total"], "uptime": status["server"]["uptime"], "container": content, "space": fs_space()[FTP_FS_PATH]}), mimetype="application/json")
def ftp_client(request, mode): path = urllib.url2pathname(request.POST.get("dir", request.GET.get("dir", "/"))) action = request.POST.get("action", request.GET.get("action", "show")) flag = request.POST.get("flag", request.GET.get("flag", None)) proftpd = Proftpd(request.user) ftp_client = proftpd.path(path) if not ftp_client.path_is_valid(): return HttpResponseBadRequest() """ The user is making a request which need a form to be filled in. """ if request.method == "GET": action = request.GET.get("action", "show") if action == "mkdir": return render_to_response("proftpd/window_mkdir.django.html") elif action == "upload": return render_to_response("proftpd/window_upload.django.html") elif action == "change_permission": if request.user.is_superuser: users = Users.objects.all() groups = unique(Groups.objects.all().values_list("groupname", flat=True)) else: users = ftp_client.ftp_user.peers() groups = ftp_client.ftp_user.groups() permissions = ftp_client.permissions() print permissions["all"] return render_to_response("proftpd/window_perm_change.django.html", {"selected_groups": permissions["group"], "selected_users": permissions["user"], "default": permissions["all"][""], "users": users, "groups": groups}) else: return render_to_response("proftpd/ftp_client.django.html", {"content": ftp_client.dir()}, context_instance=RequestContext(request)) else:# request == "POST" if action == "show": template = get_template("proftpd/browser.django.html") context = Context({"content": ftp_client.dir()}) return HttpResponse(template.render(context), mimetype="text/html") elif action == "info": template = get_template("proftpd/info_browser.django.html") context = Context({"info": ftp_client.info()}) return HttpResponse(template.render(context), mimetype="text/html") elif action == "change_permission": # Getting the permissions given according to the following scheme: # {"default": perm1, "user": {user1: perm2, user2: perm3}, "group": # {group1: perm4}} permissions = request.POST.get("permissions", None) if permissions: try: data = json.loads(permissions) except: # Damn... returng an error return HttpResponse(json.dumps({"ok": 0, "msg": _("Error occurred while serializing permissions")}), mimetype="application/json") # Setting he new permissions ftp_client.set_permissions(data) # Updating the config if not proftpd.update_config(): return HttpResponse(json.dumps({"ok": 0, "msg": _("Error occurred while saving the new configuration")}), mimetype="application/json") if ftp_client.is_dir: msg = _("The directory's permissions have been changed") else: msg = _("The file's permissions have been changed") return HttpResponse(json.dumps({"ok": 1, "msg": msg}), mimetype="application/json") elif action == "delete": if flag == "info": if ftp_client.is_file: msg = _('Are you sure you want to delete the file "%(name)s"?' % {"name": ftp_client.name}) else: msg = _('Are you sure you want to delete the directory "%(name)s"? The contents of the directory will also be deleted.' % {"name": ftp_client.name}) return HttpResponse(json.dumps({"confirm": msg}), mimetype="application/json") else: return HttpResponse(json.dumps(ftp_client.delete()), mimetype="application/json") elif action == "mkdir": name = request.POST.get("name", "New Folder") return HttpResponse(json.dumps(ftp_client.mkdir(name)), mimetype="application/json") elif action == "upload": response = ftp_client.upload(request.FILES['file'], \ request.META['REMOTE_ADDR']) return HttpResponse(response, mimetype='text/html') elif action == "download": if ftp_client.has_perm("READ", ftp_client.path) and ftp_client.is_file: return HttpResponse(json.dumps({"ok": 1, "redir": FTP_FILES_URL % ftp_client.download(request.META['REMOTE_ADDR'])}), mimetype="application/json") else: return HttpResponse(json.dumps({"ok": 0, "msg": _("Access denied")}), mimetype="application/json") else: log(3, "proftpd_app - ftp_client", "Strange action '%s'" % action) return HttpResponseBadRequest()