Projet

Général

Profil

eoleuser.py

/usr/share/python-support/python-scribe-backend/scribe/eoleuser.py corrigé - Joël Cuissinat, 19/04/2011 11:24

Télécharger (23,8 ko)

 
1
# -*- coding: utf-8 -*-
2
###########################################################################
3
# Eole NG - 2009
4
# Copyright Pole de Competence Eole  (Ministere Education - Academie Dijon)
5
# Licence CeCill  cf /root/LicenceEole.txt
6
# eole@ac-dijon.fr
7
#
8
# eoleuser.py
9
#
10
# librairie pour la gestion des utilisateurs scribe
11
#
12
###########################################################################
13
"""
14
    librairies objets de gestion des comptes utilisateurs scribe
15
    User
16
    Parent
17
    Eleve
18
    Parent
19
    Autres
20
    Machines
21
"""
22
from re import match
23
from shutil import rmtree
24
from os import system, chmod, makedirs, symlink, remove
25
from os.path import join, islink, exists, isdir
26
from subprocess import Popen, PIPE
27
from ldap import MOD_REPLACE
28
from scribe import eoletools as tool
29
from scribe.eoleldap import Ldap, LdapEntry
30
from scribe.eolegroup import Group
31
from scribe.entlogin import get_one_entlogin
32
from scribe.ldapconf import USER_DN, USER_FILTER, SMB_SERVEUR, SPOOL_MAIL, \
33
HOME_PATH, MAIL_ADMIN, GROUP_FILTER, BRANCHE, CIVILITES, MAIL_DOMAIN
34
from scribe.errors import MissingUserCreateKey, EmptyUserCreateKey, \
35
NotIntValue, BadLogin
36

    
37
#Librairies de fonction
38
def get_quota(login):
39
    """ renvoit le quota disque pour un utilisateur """
40
    cmd = "/usr/bin/quota -w %s" % login
41
    prev = Popen(cmd, stdout=PIPE, stderr=PIPE, shell=True)
42
    lines = prev.communicate()[0].splitlines()
43
    if len(lines) < 2:
44
        return 0
45
    else:
46
        # nécessité d'un try ?
47
        nb_blocks = lines[2].split()[2]
48
        # on retourne la limite en Mo
49
        return (int(nb_blocks))/1024
50

    
51
def set_quota(login, quota=''):
52
    """ applique de nouveau quota disque pour login
53
        @quota: int (str admis)
54
    """
55
    if type(quota) != int:
56
        try:
57
            quota = int(quota)
58
        except:
59
            raise NotIntValue
60
    # test de la partition (/home ou /)
61
    ret = system('mount | grep -q " /home "')
62
    if ret == 0:
63
        mnt = '/home'
64
    else:
65
        mnt = '/'
66
    cmd = "/usr/sbin/quotatool -b -u %s -q %dM -l %dM %s"
67
    retour = system(cmd % (login, quota, quota*2, mnt))
68
    return not retour
69

    
70
def send_first_mail(mail):
71
    """
72
        Envoi du mail d'ouverture d'une boîte locale
73
    """
74
    subject = "Ouverture de votre compte de messagerie"
75
    body = "Bienvenue sur votre messagerie."
76
    system("""echo "%s" | mail %s -a "FROM: %s" -s "%s"\n""" % (body, mail,
77
                                                                MAIL_ADMIN,
78
                                                                subject))
79

    
80
def gen_common_attrs(login, **args):
81
    """
82
    Gestion des attibuts communs
83
    """
84
    attrs = []
85
    attrs.append((MOD_REPLACE, 'cn', "%(prenom)s %(nom)s" % args ))
86
    attrs.append((MOD_REPLACE, 'sn', args['nom'] ))
87
    attrs.append((MOD_REPLACE, 'givenName', args['prenom'] ))
88
    attrs.append((MOD_REPLACE, 'displayName', "%(prenom)s %(nom)s" % args ))
89
    attrs.append((MOD_REPLACE, 'gecos', tool.replace_cars("%(prenom)s %(nom)s" % args) ))
90
    today = tool.format_current_date()
91
    attrs.append((MOD_REPLACE, 'LastUpdate', today))
92
    if args['entlogin']:
93
        # affectation immédiate
94
        entlogin = get_one_entlogin()
95
        if not entlogin:
96
            entlogin = login
97
    else:
98
        entlogin = login
99
    attrs.append((MOD_REPLACE, 'ENTPersonLogin', entlogin))
100
    attrs.append((MOD_REPLACE, 'ENTPersonJointure', 'ENT'))
101
    if tool.not_empty(args, 'entprofil'):
102
        attrs.append((MOD_REPLACE, 'ENTPersonProfils', args['entprofil']))
103
    if tool.not_empty(args, 'patronyme'):
104
        patro = args['patronyme']
105
    else:
106
        patro = args['nom']
107
    attrs.append((MOD_REPLACE, 'ENTPersonNomPatro', patro))
108
    if tool.not_empty(args, 'civilite') and args['civilite'].isalnum():
109
        attrs.append((MOD_REPLACE, 'codecivilite', args['civilite'] ))
110
        if args['civilite'] == '3':
111
            sexe = 'F'
112
            titre = 'Mlle'
113
        elif args['civilite'] == '2':
114
            sexe = 'F'
115
            titre = 'Mme'
116
        else:
117
            titre = 'M.'
118
            sexe = 'M'
119
        attrs.append((MOD_REPLACE, 'ENTPersonSexe', sexe))
120
        attrs.append((MOD_REPLACE, 'personalTitle', titre))
121
    if tool.not_empty(args, 'date'):
122
        # on part du principe que la date a été traitée en aval
123
        attrs.append((MOD_REPLACE, 'dateNaissance', args['date']))
124
        attrs.append((MOD_REPLACE, 'ENTPersonDateNaissance', args['date']))
125
    if tool.not_empty(args, 'prenom2'):
126
        attrs.append((MOD_REPLACE, 'ENTPersonAutresPrenoms', args['prenom2']))
127
    if tool.not_empty(args, 'int_id'):
128
        attrs.append((MOD_REPLACE, 'intid', args['int_id']))
129
    return attrs
130

    
131
#  MAY  ( ENTPersonCentresInteret $
132
#         ENTPersonAdresse $
133
#         ENTPersonCodePostal $
134
#         ENTPersonVille $
135
#         ENTPersonPays $
136
#         ENTPersonAlias $
137
#         ENTPersonStructRattach $
138
#         ENTPersonFonctions $
139
#         ENTPersonProfils $
140

    
141
def gen_enteleve_attrs(**args):
142
    """
143
    Gestion des attributs ENTEleve
144
    """
145
    attrs = []
146
    attrs.append((MOD_REPLACE, 'ENTEleveStatutEleve', 'ELEVE'))
147
    attrs.append((MOD_REPLACE, 'ENTEleveMEF', args['niveau']))
148
    attrs.append((MOD_REPLACE, 'ENTEleveLibelleMEF', args['niveau']))
149
    attrs.append((MOD_REPLACE, 'ENTEleveNivFormation', '-'))
150
    attrs.append((MOD_REPLACE, 'ENTEleveFiliere', '-'))
151
    attrs.append((MOD_REPLACE, 'ENTEleveEnseignements', '-'))
152
    attrs.append((MOD_REPLACE, 'ENTEleveClasses', '%s$%s' % (BRANCHE,
153
                                                    args['classe'])))
154
    attrs.append((MOD_REPLACE, 'ENTEleveMajeur', '-'))
155
    return attrs
156

    
157

    
158
#  MAY  ( ENTEleveVilleNaissance $
159
#         ENTEleveDeptNaissance $
160
#         ENTElevePaysNaissance $
161
#         ENTEleveParents $
162
#         ENTEleveAutoriteParentale $
163
#         ENTElevePersRelEleve1 $
164
#         ENTEleveQualitePersRelEleve1 $
165
#         ENTElevePersRelEleve2 $
166
#         ENTEleveQualitePersRelEleve2 $
167
#         ENTEleveBoursier $
168
#         ENTEleveRegime $
169
#         ENTEleveTransport $
170
#         ENTEleveMEFRattach $
171
#         ENTEleveNivFormationDiplome $
172
#         ENTEleveSpecialite $
173
#         ENTEleveGroupes $
174
#         ENTEleveEnsRespStage $
175
#         ENTEleveEnsTutStage $
176
#         ENTEleveEntrTutStage $
177
#         ENTEleveEntrAutres $
178
#         ENTEleveDelegClasse $
179
#         ENTEleveDelegAutres $
180
#         ENTEleveMajeurAnticipe
181

    
182
def gen_radius_attrs(groupid=None):
183
    """
184
    Gestion des attributs Radius
185
    """
186
    attrs = []
187
    if groupid is not None:
188
        attrs.append((MOD_REPLACE, 'radiusTunnelPrivateGroupId', groupid))
189
    attrs.append((MOD_REPLACE, 'radiusTunnelType', 'VLAN'))
190
    attrs.append((MOD_REPLACE, 'radiusFilterId', 'Enterasys:version=1:policy=Enterprise User'))
191
    attrs.append((MOD_REPLACE, 'radiusTunnelMediumType', 'IEEE-802'))
192
    return attrs
193

    
194

    
195
def gen_profil(profil, login):
196
    """
197
        Génération du sambaProfilePath selon le profil demandé
198
    """
199
    profil = int(profil)
200
    if profil == 2:
201
        # profil obligatoire #1
202
        return "\\\\%s\\netlogon\\profil" % SMB_SERVEUR
203
    if profil == 3:
204
        # profil obligatoire #2
205
        return "\\\\%s\\netlogon\\profil2" % SMB_SERVEUR
206
    if profil == 4:
207
        # profil itinérant
208
        return "\\\\%s\\%s\\profil" % (SMB_SERVEUR, login)
209
    # profil local à la station
210
    return ""
211

    
212
def gen_common_devdir(login, homedir):
213
    """
214
        Partie commune pour _gen_devoirdir
215
    """
216
    perso = join(homedir, 'perso')
217
    # le partage "devoirs" /home/l/login/devoirs
218
    dev_part = join(homedir, 'devoirs')
219
    # le dossier U:\devoirs /home/l/login/perso/devoirs
220
    dev_perso = join(perso, 'devoirs')
221
    for rep in [dev_part, dev_perso]:
222
        if islink(rep):
223
            remove(rep)
224
        if not exists(rep):
225
            makedirs(rep)
226
        system('chmod 0750 %s' % rep)
227
        system('chown -PR %s %s' % (login, rep))
228
        system('setfacl -PRm u:%s:rwx %s'%(login, rep))
229
        system('setfacl -dPRm u:%s:rwx %s'%(login, rep))
230

    
231

    
232
class User(LdapEntry):
233
    """
234
        Meta Classe pour la gestion des utilisateurs Eole
235
    """
236
    must_args = ['login', 'password']
237
    may_args = {'key2':'default2'}
238
    _type = None
239
    profil = None
240
    user_add_params = ""
241
    has_ftp = False
242
    has_samba = False
243

    
244
    def add_one(self, **args):
245
        """
246
            ajout d'un utilisateur (mode déconnecté)
247
        """
248
        self.ldap_admin.connect()
249
        self._add(**args)
250
        self.ldap_admin.close()
251

    
252
    def _add(self, **args):
253
        """
254
            Ajoute un utilisateur
255
            **args
256
        """
257
        self.filter_must_args(args)
258
        self.filter_may_args(args)
259
        if match("^[a-zA-Z0-9.\-_]*$", args['login']) is None:
260
            raise BadLogin("Login \"%s\" invalide !" % args['login'])
261
        self._test_available_name(args['login'])
262
        # FIXME : fixes #327 mais est-ce le bon endroit ?
263
        if tool.not_empty(args, 'date'):
264
            args['date'] = tool.deformate_date(args['date'])
265
        if self.has_samba:
266
            user_add_args = self.get_smbldap_useradd_args(**args)
267
            self.exec_smbldap_useradd(user_add_args)
268
            self.c_mod_password(args['login'], args['password'])
269
            if args['change_pwd']:
270
                self.password_must_change(args['login'])
271

    
272
        if self.has_ftp:
273
            self._gen_ftpdir(args['login'])
274

    
275
        self._add_perso(**args)
276

    
277
        self._add_scribe_user(**args)
278
        #self._add_ent_entrys(args)
279
        if self.has_samba or self.has_ftp:
280
            set_quota(args['login'], args['quota'])
281

    
282
    def filter_must_args(self, args):
283
        """
284
            test la présence des arguments obligatoires
285
        """
286
        for arg in self.must_args:
287
            if arg not in args:
288
                raise MissingUserCreateKey(arg)
289
            if args[arg] == '':
290
                raise EmptyUserCreateKey(arg)
291

    
292
    def filter_may_args(self, args):
293
        """
294
            remplie les valeurs par défaut des valeurs
295
            facultatives non renseignées
296
        """
297
        for arg in self.may_args:
298
            if arg not in args:
299
                args[arg] = self.may_args[arg]
300

    
301
    def get_smbldap_useradd_args(self, **args):
302
        """
303
            gestion des paramètres smbldap
304
            à redéfinir dans les sous-classes
305
        """
306
        return {}
307

    
308
    def exec_smbldap_useradd(self, user_add_args):
309
        """
310
            éxécute smbldap-useradd
311
        """
312
        cmd_arguments = self.user_add_params % user_add_args
313
        cmd = "/usr/sbin/smbldap-useradd %s" % cmd_arguments
314
        pop = Popen(cmd, shell=True, stdout=PIPE, stderr=PIPE, close_fds=True)
315
        if pop.wait() not in [0, None]:
316
            err = pop.stdout.read()
317
            raise Exception("Erreur d'ajout samba : %s" % err)
318
        return True
319

    
320
    def _add_perso(self, login, **args):
321
        """
322
            Crée les différents répertoires de l'utilisateur
323
        """
324
        pass
325

    
326
    def _add_scribe_user(self, login, **args):
327
        """
328
            Ajoute les spécificités scribe dans l'annuaire
329
        """
330
        pass
331

    
332
    def _add_ent_entrys(self, args):
333
        """
334
             Ajoute les spécificités ENT dans l'annuaire
335
        """
336
        pass
337

    
338
    def _inscription(self, login, groupe, sync=True):
339
        """
340
            Inscription d'un utilisateur à un groupe
341
        """
342
        if not self.has_ftp:
343
            return True
344
        grp = Group()
345
        grp.ldap_admin = self.ldap_admin
346
        gtype = grp.c_get_group_type(groupe)
347
        if self.profil != 'eleve' and gtype in ['Classe', 'Niveau', 'Option']:
348
            # groupes réservés élèves
349
            return True
350
        if self.profil != 'enseignant' and gtype in ['Matiere', 'Equipe']:
351
            # groupe réservés enseignants
352
            return True
353
        cmd = "/usr/sbin/smbldap-groupmod -m %s %s &>/dev/null"
354
        res = system(cmd % (login, groupe))
355
        if sync:
356
            self._gen_ftpdir(login)
357
        return res == 0
358

    
359
    def _desinscription(self, login, groupe, sync=True):
360
        """
361
            Désinscrition d'un utilisateur d'un groupe
362
        """
363
        if not self.has_ftp:
364
            return True
365
        cmd = "/usr/sbin/smbldap-groupmod -x %s %s &>/dev/null"
366
        res = system(cmd % (login, groupe))
367
        # cas eleve + option
368
        if sync:
369
            self._gen_ftpdir(login)
370
        return res == 0
371

    
372
    def _gen_ftpdir(self, login, homedir=None):
373
        """
374
            Gestion du répertoire ".ftp"
375
        """
376
        if homedir is None:
377
            homedir = self._get_attr(login, 'homeDirectory')[0].strip()
378
        ftpdir = join(homedir, '.ftp')
379
        system("rm -rf %s" % ftpdir)
380
        makedirs(ftpdir)
381
        system('/bin/chown %s %s' % (login, ftpdir))
382
        system('setfacl -bk %s' % ftpdir)
383
        chmod(ftpdir, 0500)
384
        homedir = join(HOME_PATH, homedir[6:])
385
        symlink(join(homedir, 'perso'), join(ftpdir, 'perso'))
386
        user_groups = self._get_user_groups(login)
387
        for group in user_groups:
388
            for share, sharedir in self._get_group_sharedirs(group):
389
                if share not in ['icones$', 'groupes']:
390
                    if HOME_PATH != '/home':
391
                        sharedir = sharedir.replace('/home', HOME_PATH)
392
                    symlink(sharedir, join(ftpdir, share))
393

    
394
    def _gen_groupedir(self, login, homedir=None):
395
        """
396
            Gestion du répertoire "groupes"
397
        """
398
        if homedir is None:
399
            homedir = self._get_attr(login, 'homeDirectory')[0].strip()
400
        groupedir = join(homedir, 'groupes')
401
        system('rm -rf %s' % groupedir)
402
        makedirs(groupedir)
403
        system('/bin/chown %s %s' % (login, groupedir))
404
        system('setfacl -bk %s' % groupedir)
405
        # empêcher l'écriture à la racine
406
        chmod(groupedir, 0500)
407

    
408
    def _gen_devdir(self, login, homedir=None):
409
        """
410
            Génération du répertoire "devoirs"
411
        """
412
        # à redéfinir dans les sous-classes si nécessaire
413
        pass
414

    
415
    def get_attrs(self, login, attrs):
416
        """
417
            renvoie la valeur des attributs attrs pour le user 'user'
418
            avec connexion ldap
419
        """
420
        self.ldap_admin.connect()
421
        res = self._get_attrs(login, attrs)
422
        self.ldap_admin.close()
423
        return res
424

    
425
    def get_attr(self, login, attr):
426
        """
427
            renvoie la valeur d'un attribut
428
            avec connexion ldap
429
        """
430
        self.ldap_admin.connect()
431
        res = self._get_attr(login, attr)
432
        self.ldap_admin.close()
433
        return res
434

    
435
    def set_attr(self, login, attr, value):
436
        """
437
        met à jour un a attribut
438
        """
439
        self.ldap_admin.connect()
440
        self._set_attr(login, attr, value)
441
        self.ldap_admin.close()
442

    
443
    def _get_attrs(self, login, attrs):
444
        """
445
            renvoie la valeur des attributs attrs pour le user 'login'
446
            attrs : ["attr1","attr2"] ou "attr1"
447
        """
448
        return self.ldap_admin._search_one("(&%s(uid=%s))" % (
449
                                USER_FILTER, login), attrs)
450

    
451
    def _get_attr(self, login, attr):
452
        """
453
            renvoie la valeur d'un attribut
454
        """
455
        return self._get_attrs(login, [attr]).get(attr, [])
456

    
457
    def _set_attr(self, login, attribut, value):
458
        """
459
            met à jour un attribut
460
        """
461
        if value == '':
462
            value = []
463
        user_dn = USER_DN % dict(uid=login, _type=self._type)
464
        data = [((MOD_REPLACE, attribut, value))]
465
        self.ldap_admin._modify(user_dn, data)
466

    
467
    def delete(self, login, remove_data=False, delete_resp=False):
468
        """
469
            supprime un utilisateur
470
        """
471
        self._delete(login, remove_data=remove_data, need_connect=True,
472
                     delete_resp=delete_resp)
473

    
474
    def _delete(self, login, remove_data=False, need_connect=False, delete_resp=False):
475
        """
476
            supprime un utilisateur
477
        """
478
        if self.has_samba:
479
            if remove_data:
480
                res = system('/usr/sbin/smbldap-userdel -r "%s"' % login)
481
            else:
482
                res = system('/usr/sbin/smbldap-userdel "%s"' % login)
483
                tool.move_user_datas(login)
484
            return res == 0
485
        else:
486
            if need_connect:
487
                self.ldap_admin.connect()
488
            user_dn = USER_DN % dict(uid=login, _type=self._type)
489
            self.ldap_admin._delete(user_dn)
490
            if need_connect:
491
                self.ldap_admin.close()
492
            if remove_data:
493
                perso = join(HOME_PATH, login[0], login)
494
                rmtree(perso, ignore_errors=True)
495
                maildir = join(SPOOL_MAIL, login)
496
                rmtree(maildir, ignore_errors=True)
497
            else:
498
                tool.move_mail_datas(login)
499

    
500
    def auth(self, login, password):
501
        """
502
            authentifie un utilisateur
503
        """
504
        authldap = Ldap(binddn=USER_DN % dict(uid=login, _type=self._type),
505
                        passwd=password)
506
        try:
507
            authldap.connect()
508
            authldap.close()
509
            return True
510
        except:
511
            authldap.close()
512
            return False
513

    
514
    def get_user_groups(self, login):
515
        """
516
            renvoie la liste des groupes d'un utilisateur
517
            avec connexion ldap
518
        """
519
        self.ldap_admin.connect()
520
        res = self._get_user_groups(login)
521
        self.ldap_admin.close()
522
        return res
523

    
524
    def _get_user_groups(self, login):
525
        """
526
            renvoie la liste des groupes auxquels est inscrit
527
            un utilisateur
528
        """
529
        res = self.ldap_admin._search("(&%s(memberUid=%s))" % (
530
                                GROUP_FILTER, login), 'cn')
531
        groups = []
532
        for group in res:
533
            groups.append(group[1]['cn'][0])
534
        groups.sort()
535
        return groups
536

    
537
    def _touch(self, login):
538
        """
539
            Mise à jour de l'attribut LastUpdate
540
        """
541
        self._set_attr(login, 'LastUpdate', tool.format_current_date())
542

    
543
    def _get_ead_type(self, login):
544
        """
545
        Renvoie le type d'utilisateur en fonction du login
546
        (pour les formulaires EAD)
547
        """
548
        res = self._get_attr(login, 'objectClass')
549
        if res:
550
            users = {
551
                    #'Eleves': 'eleve',
552
                    'Eleves': 'pupil',
553
                    #'administrateur': 'enseignant',
554
                    'administrateur': 'teacher',
555
                    'responsable': 'responsable',
556
                    'administratif': 'administratif',
557
                    'autre': 'autre'
558
                    }
559
            for objectclass, _type in users.items():
560
                if objectclass in res:
561
                    return _type
562
        raise Exception("utilisateur %s inconnu" % login)
563

    
564
    def _mod_civilite(self, login, civilite):
565
        """
566
        modifications des attributs utilisateurs
567
        liés à la civilité
568
        """
569
        for civ in CIVILITES:
570
            if civ['code'] == civilite:
571
                self._set_attr(login, 'ENTPersonSexe', civ['sexe'])
572
                self._set_attr(login, 'personalTitle', civ['title'])
573
                self._set_attr(login, 'codecivilite', civilite)
574
                break
575

    
576
    def _mod_date(self, login, date):
577
        """
578
        modifications des attributs utilisateurs
579
        liés à la date de naissance
580
        la date doit être pré-traitée et envoyée
581
        au format : aaaammjj
582
        """
583
        if len(date) != 8:
584
            raise Exception("Erreur dans le format de la date de naissance")
585
        self._set_attr(login, 'ENTPersonDateNaissance', date)
586
        self._set_attr(login, 'dateNaissance', date)
587

    
588
    def _mod_mail(self, login, mailtype, mail=''):
589
        """
590
        modifie le compte mail d'un utilisateur
591
        FIXME : ne devrait pas être dispo pour un élève
592
        login : login de l'utilisateur
593
        mailtype : perso/internet/restreint/aucun
594
        mail : adresse si mailtype == 'perso'
595
        """
596
        if mailtype == 'local':
597
            # compatibilité avec l'ancienne valeur
598
            mailtype = 'internet'
599
        if mailtype == 'perso' and mail != '':
600
            self._set_mailperso(login, mail)
601
        elif mailtype in ['internet', 'restreint']:
602
            self._set_localmail(login, domaine=mailtype)
603
        elif mailtype == 'aucun':
604
            self._set_mailperso(login, '')
605

    
606
    def _set_mailperso(self, login, mail):
607
        """
608
        utilisation d'une adresse mail personnalisée
609
        """
610
        self._set_attr(login, 'mailDir', [])
611
        self._set_attr(login, 'mailHost', [])
612
        self._set_attr(login, 'mail', mail)
613

    
614
    def get_maildir(self, login):
615
        """
616
        renvoie le chemin du maildir
617
        """
618
        if self.has_samba:
619
            return join(HOME_PATH, login[0], login, 'MailDir') + '/'
620
        else:
621
            return join(SPOOL_MAIL, login) + '/'
622

    
623
    def _set_localmail(self, login, domaine='internet'):
624
        """
625
        utilisation d'une adresse mail locale
626
        """
627
        maildir = self.get_maildir(login)
628
        mail = "%s@%s" % (login, MAIL_DOMAIN[domaine])
629
        self._set_attr(login, 'mailDir', maildir)
630
        self._set_attr(login, 'mailHost', 'localhost')
631
        self._set_attr(login, 'mail', mail)
632
        # mail d'ouverture si necessaire
633
        if not isdir(join(maildir, 'cur')):
634
            send_first_mail(mail)
635
        return True
636

    
637
    def get_profil(self, login):
638
        """ renvoie le profil d'un utilisateur
639
            1 local
640
            2 obligatoire-1
641
            3 obligatoire-2
642
            4 itinérant
643
        """
644
        profil = self.get_attr(login, 'sambaProfilePath')
645
        if profil == []:
646
            return 1
647
        if "profil2" in profil[0]:
648
            return 3
649
        if "netlogon" in profil[0]:
650
            return 2
651
        return 4
652

    
653
    def get_type(self, login):
654
        """
655
        renvoit le type de l'utilisateur
656
        """
657
        self.ldap_admin.connect()
658
        res = self._get_type(login)
659
        self.ldap_admin.close()
660
        return res
661

    
662
    def _get_type(self, login):
663
        """
664
        renvoit le type de l'utilisateur (mode connecté)
665
        """
666
        users = {
667
                'Eleves': 'eleve',
668
                'administrateur': 'enseignant',
669
                'responsable': 'responsable',
670
                'administratif': 'administratif',
671
                'autre': 'autre'
672
                }
673
        filtre = "(&%s(uid=%s))" % (USER_FILTER, login)
674
        res = self.ldap_admin._search_one(filtre, 'objectClass')
675
        if res.has_key('objectClass'):
676
            for objectclass, module in users.items():
677
                if objectclass in res['objectClass']:
678
                    return module
679
        raise Exception("Utilisateur %s inconnu" % login)
680

    
681
    ###############################################
682
    # Methodes spécifiques aux utilisateurs Samba #
683
    ###############################################
684

    
685
    def _update_shell(self, login, active=True):
686
        """
687
        activation/desactivation du shell utilisateur
688
        """
689
        if self.has_samba:
690
            if active:
691
                self._set_attr(login, 'loginShell', '/bin/bash')
692
            else:
693
                self._set_attr(login, 'loginShell', '/bin/false')
694

    
695
    def _set_profil(self, login, profil):
696
        """
697
        modifie le sambaProfilePath d'un utilisateur 1-2-3-4
698
        """
699
        if self.has_samba:
700
            self._set_attr(login, 'sambaProfilePath',
701
                           gen_profil(profil, login))
702

    
703
    def c_mod_password(self, login, passwd):
704
        """
705
            Modifie le mot de passe d'un utilisateur
706
        """
707
        if self.has_samba:
708
            cmd = ['/usr/share/eole/backend/passwd-eole.pl', '-u', login, '-p', passwd]
709
            prev = Popen(cmd, stdout=PIPE, stderr=PIPE)
710
        else:
711
            passwd = passwd.replace('"', '\\"')
712
            self._set_attr(login, 'userPassword', tool.sshaDigest(passwd))
713

    
714
    def password_must_change(self, login):
715
        """
716
            Changement de mot de passe obligatoire$
717
        """
718
        if self.has_samba:
719
            system('/usr/bin/net sam set pwdmustchangenow %s yes &>/dev/null' % (login))
720

    
721
class Machine(User):
722
    """
723
        classe pour les comptes machine
724
    """
725
    pass
726