Projet

Général

Profil

slc.py

brouillon pour sortir les classes facilitant la manipulation des entées LDAP du module scribe - Benjamin Bohard, 15/11/2016 12:09

Télécharger (7,25 ko)

 
1
#-*-coding:utf-8-*-
2
###########################################################################
3
# Eole NG - 2016
4
# Copyright Pole de Competence Eole  (Ministere Education - Academie Dijon)
5
# Licence CeCill  cf /root/LicenceEole.txt
6
# eole@ac-dijon.fr
7
#
8
# slc.py
9
#
10
# script de changement d’attribut ldap
11
#
12
###########################################################################
13

    
14
# importation de la configuration ldap pour établir la connexion
15
import yaml
16

    
17
ldapconf = yaml.load()
18

    
19
from os import system, makedirs, unlink, close
20
from os.path import isdir, join, basename
21
from tempfile import mkstemp, mktemp
22
from datetime import datetime, timedelta
23
from shutil import move, rmtree
24
import codecs
25
from os.path import getsize
26
from pyeole.process import system_code, system_out
27
from pyeole.service import service_code
28
from pyeole.deprecation import deprecated
29

    
30
try:
31
    from creole.eosfunc import load_container_var
32
    conteneurs = load_container_var()
33
except:
34
    conteneurs = {}
35

    
36
def to_list(data):
37
    """
38
        formatage chaine ou liste en liste sans doublons ;)
39
    """
40
    if data is None:
41
        return data
42
    elif data == '':
43
        return []
44
    elif not hasattr(data, '__iter__'):
45
        return list(set([data]))
46
    else:
47
        return list(set(data))
48

    
49

    
50
from ldapconf import SUFFIX, ROOT_DN, USER_FILTER, ldap_server, ldap_passwd
51
from eoletools import to_list
52
import ldap
53

    
54
def is_system_user(user):
55
    """
56
        indique si le login proposé est déjà un utilisateur système
57
    """
58
    user = user.lower()
59
    with open('/etc/passwd', 'r') as passfile:
60
        users = [line.split(':')[0] for line in passfile.readlines()]
61
    return user in users
62

    
63
class Ldap(object):
64
    """
65
        Interface de connection à un serveur ldap
66
    """
67

    
68
    def __init__(self, serveur=None, passwd=None, binddn=None):
69
        if serveur is None:
70
            self.serveur = ldap_server
71
        else:
72
            self.serveur = serveur
73
        if passwd is None:
74
            self.passwd = ldap_passwd
75
            self.local_passwd = True
76
        else:
77
            self.passwd = passwd
78
            self.local_passwd = False
79
        if binddn == None:
80
            self.binddn = ROOT_DN
81
        else:
82
            self.binddn = binddn
83
        self.connexion = None
84

    
85
    def __enter__(self):
86
        self.connect()
87

    
88
    def __exit__(self):
89
        self.close()
90

    
91
    def reload_pwd(self):
92
        """
93
            recharge le mot de passe
94
        """
95
        if self.local_passwd:
96
            #reload(backend_conf)
97
            self.passwd = ldap_passwd
98

    
99
    def connect(self):
100
        """
101
            binding ldap si nécessaire
102
        """
103
        if not self.connexion:
104
            # FIXME : inutile avec execfile
105
            #self.reload_pwd()
106
            self.connexion = ldap.open(self.serveur)
107
            self.connexion.simple_bind_s(self.binddn, self.passwd)
108

    
109
    def close(self):
110
        """
111
            fermeture de la connexion ldap
112
        """
113
        if self.connexion:
114
            self.connexion.unbind()
115
            self.connexion = None
116

    
117
    def _add(self, dn , data):
118
        """
119
            ajout d'une entrée ldap
120
        """
121
        self.connexion.add_s(dn, data)
122

    
123
    def _delete(self, dn):
124
        """
125
            suppression d'une entrée ldap
126
        """
127
        self.connexion.delete(dn)
128

    
129
    def _modify(self, dn, data):
130
        """
131
            modification d'une entrée ldap
132
        """
133
        self.connexion.modify_s(dn, data)
134

    
135
    def _search(self, filtre, attrlist=None, suffix=None):
136
        """
137
            recherche dans l'annuaire
138
        """
139
        if suffix == None:
140
            suffix = SUFFIX
141
        attrlist = to_list(attrlist)
142
        return self.connexion.search_s(suffix, ldap.SCOPE_SUBTREE,
143
                                filtre, attrlist)
144

    
145
    def _search_one(self, filtre, attrlist=None, suffix=None):
146
        """
147
           recherche une entrée dans l'annuaire
148
        """
149
        result = self._search(filtre, attrlist, suffix=suffix)
150
        if len(result) > 0 and len(result[0]) == 2:
151
            return result[0][1]
152
        else:
153
            return {}
154

    
155
class LdapEntry(object):
156
    """
157
        classe de base pour gérer les entrées ldap
158
    """
159
    def __init__(self, serveur=None, passwd=None):
160
        self.serveur = serveur
161
        self.passwd = passwd
162
        self.ldap_admin = Ldap(serveur, passwd)
163
        self.cache_etab = {'login': {}, 'group': {}}
164

    
165
from re import match
166
from shutil import rmtree
167
from os import system, chmod, makedirs, symlink, remove
168
from os.path import join, islink, exists, isdir
169
from ldap import MOD_REPLACE
170
from pyeole.process import system_out
171
from pyeole.deprecation import deprecated
172
from fichier import quota, passwd
173
from scribe import eoletools as tool
174
from pyeole.ssha import ssha_encode
175
from scribe.eolegroup import Group
176
from scribe.errors import MissingUserCreateKey, EmptyUserCreateKey, \
177
BadLogin
178

    
179
class User(LdapEntry):
180
    """
181
        Meta Classe pour la gestion des utilisateurs Eole
182
    """
183
    must_args = ['login', 'password']
184
    may_args = {'key2':'default2'}
185
    _type = None
186
    profil = None
187
    # arguments communs pour smbldap-useradd
188
    user_add_params = ['-a', '-A', '1', '-D', 'U:', '-H', 'U']
189
    has_ftp = False
190
    has_samba = False
191

    
192
    def get_attrs(self, login, attrs):
193
        """
194
            renvoie la valeur des attributs attrs pour le user 'user'
195
            avec connexion ldap
196
        """
197
        self.ldap_admin.connect()
198
        res = self._get_attrs(login, attrs)
199
        self.ldap_admin.close()
200
        return res
201

    
202
    def get_attr(self, login, attr):
203
        """
204
            renvoie la valeur d'un attribut
205
            avec connexion ldap
206
        """
207
        self.ldap_admin.connect()
208
        res = self._get_attr(login, attr)
209
        self.ldap_admin.close()
210
        return res
211

    
212
    def set_attr(self, login, attr, value):
213
        """
214
        met à jour un a attribut
215
        """
216
        self.ldap_admin.connect()
217
        self._set_attr(login, attr, value)
218
        self.ldap_admin.close()
219

    
220
    def _get_attrs(self, login, attrs):
221
        """
222
            renvoie la valeur des attributs attrs pour le user 'login'
223
            attrs : ["attr1","attr2"] ou "attr1"
224
        """
225
        return self.ldap_admin._search_one("(&%s(uid=%s))" % (
226
                                USER_FILTER, login), attrs)
227

    
228
    def _get_attr(self, login, attr):
229
        """
230
            renvoie la valeur d'un attribut
231
        """
232
        return self._get_attrs(login, [attr]).get(attr, [])
233

    
234
    def _set_attr(self, login, attribut, value):
235
        """
236
            met à jour un attribut
237
        """
238
        if value == '':
239
            value = []
240
        user_dn = self.get_user_dn(login) #USER_DN % dict(uid=login, _type=self._type, etab=etab)
241
        data = [((MOD_REPLACE, attribut, value))]
242
        self.ldap_admin._modify(user_dn, data)
243

    
244
    def auth(self, login, password):
245
        """
246
            authentifie un utilisateur
247
        """
248
        user_dn = self.get_user_dn(login)
249
        authldap = Ldap(binddn=user_dn,
250
                        passwd=password)
251
        try:
252
            authldap.connect()
253
            authldap.close()
254
            return True
255
        except:
256
            authldap.close()
257
            return False
258

    
259
    def _touch(self, login):
260
        """
261
            Mise à jour de l'attribut LastUpdate
262
        """
263
        self._set_attr(login, 'LastUpdate', tool.format_current_date())