class ServiceAccount(BaseLdapModel): # description used as description for primary groups of users base_dn = 'ou=Services,' + settings.LDAP_BASE_DN object_classes = force_bytestrings(['posixAccount', 'shadowAccount', 'inetOrgPerson', 'person']) fqdn = CharField(db_column=force_text('uid'), max_length=200, primary_key=True, validators=list(name_validators)) uid_number = IntegerField(db_column=force_text('uidNumber'), default=None, unique=True) gid_number = IntegerField(db_column=force_text('gidNumber'), default=None) # forced values display_name = CharField(db_column=force_text('displayName'), max_length=200) mail = CharField(db_column=force_text('mail'), default=None) gecos = CharField(db_column=force_text('gecos'), max_length=200, default=None) cn = CharField(db_column=force_text('cn'), max_length=200, default=None, validators=list(name_validators)) sn = CharField(db_column=force_text('sn'), max_length=200, default=None, validators=list(name_validators)) # password values user_password = CharField(db_column=force_text('userPassword'), default=None) # samba_nt_password = CharField(db_column=force_text('sambaNTPassword'), default=None) def save(self, using=None): self.cn = self.fqdn self.sn = self.fqdn self.display_name = self.fqdn self.gecos = self.fqdn self.mail = '%s@%s' % (self.fqdn, settings.PENATES_DOMAIN) self.set_next_free_value('uid_number') self.gid_number = self.uid_number super(ServiceAccount, self).save(using=using) def set_password(self, password): self.user_password = password_hash(password) self.save()
class Group(BaseLdapModel): base_dn = force_text('ou=Groups,' + settings.LDAP_BASE_DN) object_classes = force_bytestrings(['posixGroup', 'sambaGroupMapping']) # posixGroup attributes name = CharField(db_column=force_text('cn'), max_length=200, primary_key=True, validators=list(name_validators)) gid = IntegerField(db_column=force_text('gidNumber'), unique=True) members = ListField(db_column=force_text('memberUid')) description = CharField(db_column=force_text('description'), max_length=500, blank=True, default='') group_type = IntegerField(db_column=force_text('sambaGroupType'), default=None) samba_sid = CharField(db_column=force_text('sambaSID'), unique=True, default='') def save(self, using=None): self.group_type = 2 self.set_next_free_value('gid', default=10000) # noinspection PyStringFormat self.samba_sid = '%s-%d' % (get_samba_sid(), self.gid) super(Group, self).save(using=using) group_of_names = list(GroupOfNames.objects.filter(name=self.name)[0:1]) if not group_of_names: group = GroupOfNames(name=self.name, members=['cn=admin,' + settings.LDAP_BASE_DN]) group.save() else: group = group_of_names[0] new_members = ['cn=admin,' + settings.LDAP_BASE_DN] + ['uid=%s,%s' % (x, User.base_dn) for x in self.members] if new_members != group.members: group.members = new_members group.save()
class GroupOfNames(BaseLdapModel): # a copy of Group, but based on different object classes. # required by nslcd! base_dn = 'ou=CoreGroups,' + settings.LDAP_BASE_DN object_classes = force_bytestrings(['groupOfNames']) name = CharField(db_column=force_text('cn'), max_length=200, primary_key=True, validators=list(name_validators)) members = ListField(db_column=force_text('member'))
class Principal(BaseLdapModel): base_dn = 'cn=krbContainer,' + settings.LDAP_BASE_DN object_classes = force_bytestrings(['krbPrincipal', 'krbPrincipalAux', 'krbTicketPolicyAux']) name = CharField(db_column=force_text('krbPrincipalName'), primary_key=True) flags = IntegerField(db_column=force_text('krbTicketFlags'), default=None) def save(self, using=None): self.flags = 128 super(Principal, self).save(using=using)
class SambaDomain(BaseLdapModel): base_dn = settings.LDAP_BASE_DN object_classes = force_bytestrings(['sambaDomain']) rid_base = IntegerField(db_column=force_text('sambaAlgorithmicRidBase'), default=2000) sid = CharField(db_column=force_text('sambaSID')) name = CharField(db_column=force_text('sambaDomainName'), primary_key=True)
class Netgroup(BaseLdapModel): base_dn = 'ou=netgroups,' + settings.LDAP_BASE_DN object_classes = force_bytestrings(['nisNetgroup', ]) name = CharField(db_column=force_text('cn'), primary_key=True) triple = ListField(db_column=force_text('nisNetgroupTriple')) member = ListField(db_column=force_text('memberNisNetgroup'))
class User(BaseLdapModel): PRIMARY_GROUPS_DESCRIPTION = 'auto' # description used as description for primary groups of users base_dn = 'ou=Users,' + settings.LDAP_BASE_DN object_classes = force_bytestrings(['posixAccount', 'shadowAccount', 'inetOrgPerson', 'sambaSamAccount', 'person', 'AsteriskSIPUser']) name = CharField(db_column=force_text('uid'), max_length=200, primary_key=True, validators=list(name_validators)) display_name = CharField(db_column=force_text('displayName'), max_length=200) uid_number = IntegerField(db_column=force_text('uidNumber'), default=None, unique=True) gid_number = IntegerField(db_column=force_text('gidNumber'), default=None) login_shell = CharField(db_column=force_text('loginShell'), default='/bin/bash') description = CharField(db_column=force_text('description'), default='Description') jpeg_photo = ImageField(db_column=force_text('jpegPhoto'), max_length=10000000) phone = CharField(db_column=force_text('telephoneNumber'), default=None) samba_acct_flags = CharField(db_column=force_text('sambaAcctFlags'), default='[UX ]') user_smime_certificate = CharField(db_column=force_text('userSMIMECertificate'), default=None) user_certificate = CharField(db_column=force_text('userCertificate'), default=None) # forced values samba_sid = CharField(db_column=force_text('sambaSID'), default=None) primary_group_samba_sid = CharField(db_column=force_text('sambaPrimaryGroupSID'), default=None) home_directory = CharField(db_column=force_text('homeDirectory'), default=None) mail = CharField(db_column=force_text('mail'), default=None) samba_domain_name = CharField(db_column=force_text('sambaDomainName'), default=None) gecos = CharField(db_column=force_text('gecos'), max_length=200, default=None) cn = CharField(db_column=force_text('cn'), max_length=200, default=None, validators=list(name_validators)) sn = CharField(db_column=force_text('sn'), max_length=200, default=None, validators=list(name_validators)) # password values user_password = CharField(db_column=force_text('userPassword'), default=None) # samba_nt_password = CharField(db_column=force_text('sambaNTPassword'), default=None) ast_account_caller_id = CharField(db_column=force_text('AstAccountCallerID'), default=None) ast_account_context = CharField(db_column=force_text('AstAccountContext'), default='LocalSets') ast_account_DTMF_mode = CharField(db_column=force_text('AstAccountDTMFMode'), default='rfc2833') ast_account_mailbox = CharField(db_column=force_text('AstAccountMailbox'), default=None) ast_account_NAT = CharField(db_column=force_text('AstAccountNAT'), default='yes') ast_account_qualify = CharField(db_column=force_text('AstAccountQualify'), default='yes') ast_account_type = CharField(db_column=force_text('AstAccountType'), default='friend') ast_account_disallowed_codec = CharField(db_column=force_text('AstAccountDisallowedCodec'), default='all') ast_account_allowed_codec = CharField(db_column=force_text('AstAccountAllowedCodec'), default='ulaw') ast_account_music_on_hold = CharField(db_column=force_text('AstAccountMusicOnHold'), default='default') def save(self, using=None): group = self.set_gid_number() self.cn = self.name self.sn = self.name self.gecos = self.display_name self.ast_account_caller_id = self.display_name self.samba_domain_name = settings.PENATES_REALM self.mail = '%s@%s' % (self.name, settings.PENATES_DOMAIN) self.ast_account_mailbox = self.mail self.home_directory = '/home/%s' % self.name self.set_next_free_value('uid_number') self.samba_sid = '%s-%s' % (get_samba_sid(), self.uid_number) self.primary_group_samba_sid = '%s-%s' % (get_samba_sid(), self.gid_number) super(User, self).save(using=using) if group and self.name not in group.members: # noinspection PyUnresolvedReferences group.members.append(self.name) group.save() add_principal(self.principal_name) @property def principal_name(self): return '%s@%s' % (self.name, settings.PENATES_REALM) def set_gid_number(self): if self.gid_number is not None: groups = list(Group.objects.filter(gid=self.gid_number)[0:1]) else: groups = list(Group.objects.filter(name=self.name)[0:1]) if not groups: group = Group(name=self.name, gid=self.gid_number, description=self.PRIMARY_GROUPS_DESCRIPTION) group.save() else: group = groups[0] self.gid_number = group.gid return group def set_password(self, password): self.user_password = password_hash(password) self.save() change_password(self.principal_name, password) if settings.STORE_CLEARTEXT_PASSWORDS: ensure_location(self.password_filename) with codecs.open(self.password_filename, 'w', encoding='utf-8') as fd: fd.write(password) os.chmod(self.password_filename, 0o400) @property def password_filename(self): return os.path.join(settings.PKI_PATH, 'private', 'passwords', '%s.txt' % self.name) def read_password(self): if settings.STORE_CLEARTEXT_PASSWORDS: with codecs.open(self.password_filename, 'r', encoding='utf-8') as fd: return fd.read() return '' def delete(self, using=None): super(User, self).delete(using=using) delete_principal(self.principal_name) @property def user_certificate_entry(self): return CertificateEntry(self.name, organizationName=settings.PENATES_ORGANIZATION, organizationalUnitName=_('Users'), emailAddress=self.mail, localityName=settings.PENATES_LOCALITY, countryName=settings.PENATES_COUNTRY, stateOrProvinceName=settings.PENATES_STATE, altNames=[], role=USER) @property def email_certificate_entry(self): return CertificateEntry(self.name, organizationName=settings.PENATES_ORGANIZATION, organizationalUnitName=_('Users'), emailAddress=self.mail, localityName=settings.PENATES_LOCALITY, countryName=settings.PENATES_COUNTRY, stateOrProvinceName=settings.PENATES_STATE, altNames=[], role=EMAIL) @property def signature_certificate_entry(self): return CertificateEntry(self.name, organizationName=settings.PENATES_ORGANIZATION, organizationalUnitName=_('Users'), emailAddress=self.mail, localityName=settings.PENATES_LOCALITY, countryName=settings.PENATES_COUNTRY, stateOrProvinceName=settings.PENATES_STATE, altNames=[], role=SIGNATURE) @property def encipherment_certificate_entry(self): return CertificateEntry(self.name, organizationName=settings.PENATES_ORGANIZATION, organizationalUnitName=_('Users'), emailAddress=self.mail, localityName=settings.PENATES_LOCALITY, countryName=settings.PENATES_COUNTRY, stateOrProvinceName=settings.PENATES_STATE, altNames=[], role=ENCIPHERMENT)