Exemple #1
0
    def init_person_key(self, person, iotlab_key):
        """
        Returns a tuple pubkey and pkey.

        :param person Person's data.
        :type person: dict
        :param iotlab_key: SSH public key, from LDAP user's data. RSA type
            supported.
        :type iotlab_key: string
        :rtype: (string, Keypair)

        """
        pubkey = None
        if person['pkey']:
            # randomly pick first key in set
            pubkey = iotlab_key

            try:
                pkey = convert_public_key(pubkey)
            except TypeError:
                #key not good. create another pkey
                self.logger.warn("IotlabImporter: \
                                    unable to convert public \
                                    key for %s" % person['hrn'])
                pkey = Keypair(create=True)

        else:
            # the user has no keys.
            #Creating a random keypair for the user's gid
            self.logger.warn("IotlabImporter: person %s does not have a  \
                        public key" % (person['hrn']))
            pkey = Keypair(create=True)
        return (pubkey, pkey)
Exemple #2
0
    def check_gid(self, xrn=None, type=None, all=None, verbose=None):
        """Check the correspondance between the GID and the PubKey"""

        # db records
        from sfa.storage.model import RegRecord
        db_query = self.api.dbsession().query(RegRecord).filter_by(type=type)
        if xrn and not all:
            hrn = Xrn(xrn).get_hrn()
            db_query = db_query.filter_by(hrn=hrn)
        elif all and xrn:
            print "Use either -a or -x <xrn>, not both !!!"
            sys.exit(1)
        elif not all and not xrn:
            print "Use either -a or -x <xrn>, one of them is mandatory !!!"
            sys.exit(1)

        records = db_query.all()
        if not records:
            print "No Record found"
            sys.exit(1)

        OK = []
        NOK = []
        ERROR = []
        NOKEY = []
        for record in records:
             # get the pubkey stored in SFA DB
             if record.reg_keys:
                 db_pubkey_str = record.reg_keys[0].key
                 try:
                   db_pubkey_obj = convert_public_key(db_pubkey_str)
                 except:
                   ERROR.append(record.hrn)
                   continue
             else:
                 NOKEY.append(record.hrn)
                 continue

             # get the pubkey from the gid
             gid_str = record.gid
             gid_obj = GID(string = gid_str)
             gid_pubkey_obj = gid_obj.get_pubkey()

             # Check if gid_pubkey_obj and db_pubkey_obj are the same
             check = gid_pubkey_obj.is_same(db_pubkey_obj)
             if check :
                 OK.append(record.hrn)
             else:
                 NOK.append(record.hrn)

        if not verbose:
            print "Users NOT having a PubKey: %s\n\
Users having a non RSA PubKey: %s\n\
Users having a GID/PubKey correpondence OK: %s\n\
Users having a GID/PubKey correpondence Not OK: %s\n"%(len(NOKEY), len(ERROR), len(OK), len(NOK))
        else:
            print "Users NOT having a PubKey: %s and are: \n%s\n\n\
Users having a non RSA PubKey: %s and are: \n%s\n\n\
Users having a GID/PubKey correpondence OK: %s and are: \n%s\n\n\
Users having a GID/PubKey correpondence NOT OK: %s and are: \n%s\n\n"%(len(NOKEY),NOKEY, len(ERROR), ERROR, len(OK), OK, len(NOK), NOK)
Exemple #3
0
    def init_person_key(self, person, iotlab_key):
        """
        Returns a tuple pubkey and pkey.

        :param person Person's data.
        :type person: dict
        :param iotlab_key: SSH public key, from LDAP user's data. RSA type
            supported.
        :type iotlab_key: string
        :rtype: (string, Keypair)

        """
        pubkey = None
        if person['pkey']:
            # randomly pick first key in set
            pubkey = iotlab_key

            try:
                pkey = convert_public_key(pubkey)
            except TypeError:
                #key not good. create another pkey
                self.logger.warn("IotlabImporter: \
                                    unable to convert public \
                                    key for %s" % person['hrn'])
                pkey = Keypair(create=True)

        else:
            # the user has no keys.
            #Creating a random keypair for the user's gid
            self.logger.warn("IotlabImporter: person %s does not have a  \
                        public key" % (person['hrn']))
            pkey = Keypair(create=True)
        return (pubkey, pkey)
Exemple #4
0
    def import_users(self, existing_hrns, existing_records):
        # Get all users
        users = self.shell.auth_manager.users.list()
        users_dict = {}
        keys_filename = self.config.config_path + os.sep + 'person_keys.py'
        old_user_keys = load_keys(keys_filename)
        user_keys = {}
        for user in users:
            auth_hrn = self.config.SFA_INTERFACE_HRN
            if user.tenantId is not None:
                tenant = self.shell.auth_manager.tenants.find(id=user.tenantId)
                auth_hrn = OSXrn(name=tenant.name,
                                 auth=self.config.SFA_INTERFACE_HRN,
                                 type='authority').get_hrn()
            hrn = OSXrn(name=user.name, auth=auth_hrn, type='user').get_hrn()
            users_dict[hrn] = user
            old_keys = old_user_keys.get(hrn, [])
            keyname = OSXrn(xrn=hrn, type='user').get_slicename()
            keys = [
                k.public_key
                for k in self.shell.nova_manager.keypairs.findall(name=keyname)
            ]
            user_keys[hrn] = keys
            update_record = False
            if old_keys != keys:
                update_record = True
            if hrn not in existing_hrns or \
                   (hrn, 'user') not in existing_records or update_record:
                urn = OSXrn(xrn=hrn, type='user').get_urn()

                if keys:
                    try:
                        pkey = convert_public_key(keys[0])
                    except:
                        self.logger.log_exc(
                            'unable to convert public key for %s' % hrn)
                        pkey = Keypair(create=True)
                else:
                    self.logger.warn(
                        "OpenstackImporter: person %s does not have a PL public key"
                        % hrn)
                    pkey = Keypair(create=True)
                user_gid = self.auth_hierarchy.create_gid(urn,
                                                          create_uuid(),
                                                          pkey,
                                                          email=user.email)
                user_record = RegUser()
                user_record.type = 'user'
                user_record.hrn = hrn
                user_record.gid = user_gid
                user_record.authority = get_authority(hrn)
                global_dbsession.add(user_record)
                global_dbsession.commit()
                self.logger.info("OpenstackImporter: imported person %s" %
                                 user_record)

        return users_dict, user_keys
    def import_users(self, existing_hrns, existing_records):
        # Get all users
        users = self.shell.auth_manager.users.list()
        users_dict = {}
        keys_filename = self.config.config_path + os.sep + 'person_keys.py'
        old_user_keys = load_keys(keys_filename)
        user_keys = {}
        for user in users:
            auth_hrn = self.config.SFA_INTERFACE_HRN
            try:
                user_tenantId = user.tenantId
                user_email = user.email
            except AttributeError, e:
                user_tenantId = None
                user_email = None

            if user_tenantId is not None:
                #import pdb; pdb.set_trace()
                tenant = self.shell.auth_manager.tenants.find(id=user_tenantId)
                if tenant is not None:
                    auth_hrn = OSXrn(name=tenant.name, auth=self.config.SFA_INTERFACE_HRN, type='authority').get_hrn()
            hrn = OSXrn(name=user.name, auth=auth_hrn, type='user').get_hrn()
            users_dict[hrn] = user
            old_keys = old_user_keys.get(hrn, [])
            keyname = OSXrn(xrn=hrn, type='user').get_slicename()
            keys = [k.public_key for k in self.shell.compute_manager.keypairs.findall(name=keyname)]
            user_keys[hrn] = keys
            update_record = False
            if old_keys != keys:
                update_record = True
            if hrn not in existing_hrns or \
                   (hrn, 'user') not in existing_records or update_record:
                urn = OSXrn(xrn=hrn, type='user').get_urn()
                if keys:
                    try:
                        pkey = convert_public_key(keys[0])
                    except:
                        self.logger.log_exc('unable to convert public key for %s' % hrn)
                        pkey = Keypair(create=True)
                else:
                    self.logger.warn("OpenstackImporter: person %s does not have a PL public key"%hrn)
                    pkey = Keypair(create=True)
                user_gid = self.auth_hierarchy.create_gid(urn, create_uuid(), pkey, email=user_email)
                user_record = RegUser(type='user', 
                                      hrn=hrn, 
                                      gid=user_gid, 
                                      authority=get_authority(hrn))
                global_dbsession.add(user_record)
                global_dbsession.commit()
                self.logger.info("OpenstackImporter: imported person %s" % user_record)
Exemple #6
0
 def init_person_key (person, plc_keys):
     pubkey=None
     if  person['key_ids']:
         # randomly pick first key in set
         pubkey = plc_keys[0]
         try:
             pkey = convert_public_key(pubkey['key'])
         except:
             self.logger.warn('PlImporter: unable to convert public key for %s' % person_hrn)
             pkey = Keypair(create=True)
     else:
         # the user has no keys. Creating a random keypair for the user's gid
         self.logger.warn("PlImporter: person %s does not have a PL public key"%person_hrn)
         pkey = Keypair(create=True)
     return (pubkey, pkey)
Exemple #7
0
    def import_person(self, parent_hrn, person):
        """
        Register a user record 
        """
        hrn = email_to_hrn(parent_hrn, person['email'])

        # ASN.1 will have problems with hrn's longer than 64 characters
        if len(hrn) > 64:
            hrn = hrn[:64]

        self.logger.info("Import: person %s"%hrn)
        key_ids = []
        if 'key_ids' in person and person['key_ids']:
            key_ids = person["key_ids"]
            # get the user's private key from the SSH keys they have uploaded
            # to planetlab
            keys = self.shell.GetKeys(self.plc_auth, key_ids)
            key = keys[0]['key']
            pkey = None
            try:
                pkey = convert_public_key(key)
            except:
                self.logger.warn('unable to convert public key for %s' % hrn) 
            if not pkey:
                pkey = Keypair(create=True)
        else:
            # the user has no keys
            self.logger.warn("Import: person %s does not have a PL public key"%hrn)
            # if a key is unavailable, then we still need to put something in the
            # user's GID. So make one up.
            pkey = Keypair(create=True)

        # create the gid
        urn = hrn_to_urn(hrn, 'user')
        person_gid = self.AuthHierarchy.create_gid(urn, create_uuid(), pkey)
        table = SfaTable()
        person_record = SfaRecord(hrn=hrn, gid=person_gid, type="user", pointer=person['person_id'])
        person_record['authority'] = get_authority(person_record['hrn'])
        existing_records = table.find({'hrn': hrn, 'type': 'user', 'pointer': person['person_id']})
        if not existing_records:
            table.insert(person_record)
        else:
            self.logger.info("Import: %s exists, updating " % hrn)
            existing_record = existing_records[0]
            person_record['record_id'] = existing_record['record_id']
            table.update(person_record)
Exemple #8
0
 def init_person_key(person, plc_keys):
     pubkey = None
     if person['key_ids']:
         # randomly pick first key in set
         pubkey = plc_keys[0]
         try:
             pkey = convert_public_key(pubkey['key'])
         except:
             self.logger.warn(
                 'PlImporter: unable to convert public key for %s'
                 % person_hrn)
             pkey = Keypair(create=True)
     else:
         # the user has no keys. Creating a random keypair for the user's gid
         self.logger.warn(
             "PlImporter: person %s does not have a PL public key"
             % person_hrn)
         pkey = Keypair(create=True)
     return (pubkey, pkey)
Exemple #9
0
 def init_user_key (user):
     pubkey = None
     pkey = None
     if  user['keys']:
         # randomly pick first key in set
         for key in user['keys']:
              pubkey = key
              try:
                 pkey = convert_public_key(pubkey)
                 break
              except:
                 continue
         if not pkey:
             self.logger.warn('DummyImporter: unable to convert public key for %s' % user_hrn)
             pkey = Keypair(create=True)
     else:
         # the user has no keys. Creating a random keypair for the user's gid
         self.logger.warn("DummyImporter: user %s does not have a NITOS public key"%user_hrn)
         pkey = Keypair(create=True)
     return (pubkey, pkey)
Exemple #10
0
 def init_person_key (person, slab_key):
     pubkey = None
     if  person['pkey']:
         # randomly pick first key in set
         pubkey = slab_key
         
         try:
             pkey = convert_public_key(pubkey)
         except TypeError:
             #key not good. create another pkey
             self.logger.warn('SlabImporter: \
                                 unable to convert public \
                                 key for %s' % person_hrn)
             pkey = Keypair(create=True)
         
     else:
         # the user has no keys. Creating a random keypair for the user's gid
         self.logger.warn("SlabImporter: person %s does not have a  public key"%person_hrn)
         pkey = Keypair(create=True) 
     return (pubkey, pkey)
Exemple #11
0
    def check_gid(self, xrn=None, type=None, all=None, verbose=None):
        """Check the correspondance between the GID and the PubKey"""

        # db records
        from sfa.storage.model import RegRecord
        db_query = self.api.dbsession().query(RegRecord).filter_by(type=type)
        if xrn and not all:
            hrn = Xrn(xrn).get_hrn()
            db_query = db_query.filter_by(hrn=hrn)
        elif all and xrn:
            print "Use either -a or -x <xrn>, not both !!!"
            sys.exit(1)
        elif not all and not xrn:
            print "Use either -a or -x <xrn>, one of them is mandatory !!!"
            sys.exit(1)

        records = db_query.all()
        if not records:
            print "No Record found"
            sys.exit(1)

        OK = []
        NOK = []
        ERROR = []
        NOKEY = []
        for record in records:
            # get the pubkey stored in SFA DB
            if record.reg_keys:
                db_pubkey_str = record.reg_keys[0].key
                try:
                    db_pubkey_obj = convert_public_key(db_pubkey_str)
                except:
                    ERROR.append(record.hrn)
                    continue
            else:
                NOKEY.append(record.hrn)
                continue

            # get the pubkey from the gid
            gid_str = record.gid
            gid_obj = GID(string=gid_str)
            gid_pubkey_obj = gid_obj.get_pubkey()

            # Check if gid_pubkey_obj and db_pubkey_obj are the same
            check = gid_pubkey_obj.is_same(db_pubkey_obj)
            if check:
                OK.append(record.hrn)
            else:
                NOK.append(record.hrn)

        if not verbose:
            print "Users NOT having a PubKey: %s\n\
Users having a non RSA PubKey: %s\n\
Users having a GID/PubKey correpondence OK: %s\n\
Users having a GID/PubKey correpondence Not OK: %s\n" % (
                len(NOKEY), len(ERROR), len(OK), len(NOK))
        else:
            print "Users NOT having a PubKey: %s and are: \n%s\n\n\
Users having a non RSA PubKey: %s and are: \n%s\n\n\
Users having a GID/PubKey correpondence OK: %s and are: \n%s\n\n\
Users having a GID/PubKey correpondence NOT OK: %s and are: \n%s\n\n" % (len(
                NOKEY), NOKEY, len(ERROR), ERROR, len(OK), OK, len(NOK), NOK)
Exemple #12
0
    def Update(self, api, record_dict):

        logger.debug("Update: entering with record_dict=%s"%printable(record_dict))
        normalize_input_record (record_dict)
        logger.debug("Update: normalized record_dict=%s"%printable(record_dict))

        dbsession=api.dbsession()
        assert ('type' in record_dict)
        new_record=make_record(dict=record_dict)
        (type,hrn) = (new_record.type, new_record.hrn)
        
        # make sure the record exists
        record = dbsession.query(RegRecord).filter_by(type=type,hrn=hrn).first()
        if not record:
            raise RecordNotFound("hrn=%s, type=%s"%(hrn,type))
        record.just_updated()
    
        # Use the pointer from the existing record, not the one that the user
        # gave us. This prevents the user from inserting a forged pointer
        pointer = record.pointer

        # is there a change in keys ?
        new_key=None
        if type=='user':
            if getattr(new_record,'keys',None):
                new_key=new_record.keys
                if isinstance (new_key,types.ListType):
                    new_key=new_key[0]

        # take new_key into account
        if new_key:
            # update the openssl key and gid
            pkey = convert_public_key(new_key)
            uuid = create_uuid()
            urn = hrn_to_urn(hrn,type)

            email=getattr(new_record,'email',None)
            if email is None:
                email=getattr(record,'email',None)
            gid_object = api.auth.hierarchy.create_gid(urn, uuid, pkey, email = email)
            gid = gid_object.save_to_string(save_parents=True)
        
        # xxx should do side effects from new_record to record
        # not too sure how to do that
        # not too big a deal with planetlab as the driver is authoritative, but...

        # update native relations
        if isinstance (record, RegSlice):
            researcher_hrns = getattr(new_record,'reg-researchers',None)
            if researcher_hrns is not None: record.update_researchers (researcher_hrns, dbsession)

        elif isinstance (record, RegAuthority):
            pi_hrns = getattr(new_record,'reg-pis',None)
            if pi_hrns is not None: record.update_pis (pi_hrns, dbsession)
        
        # update the PLC information that was specified with the record
        # xxx oddly enough, without this useless statement, 
        # record.__dict__ as received by the driver seems to be off
        # anyway the driver should receive an object 
        # (and then extract __dict__ itself if needed)
        print "DO NOT REMOVE ME before driver.update, record=%s"%record
        new_key_pointer = -1
        try:
           (pointer, new_key_pointer) = api.driver.update (record.__dict__, new_record.__dict__, hrn, new_key)
        except:
           pass
        if new_key and new_key_pointer:
            record.reg_keys=[ RegKey (new_key, new_key_pointer)]
            record.gid = gid

        dbsession.commit()
        # update membership for researchers, pis, owners, operators
        self.update_driver_relations (api, record, new_record)
        
        return 1 
Exemple #13
0
    def Register(self, api, record_dict):
    
        logger.debug("Register: entering with record_dict=%s"%printable(record_dict))
        normalize_input_record (record_dict)
        logger.debug("Register: normalized record_dict=%s"%printable(record_dict))

        dbsession=api.dbsession()
        hrn, type = record_dict['hrn'], record_dict['type']
        urn = hrn_to_urn(hrn,type)
        # validate the type
        if type not in ['authority', 'slice', 'node', 'user']:
            raise UnknownSfaType(type) 
        
        # check if record_dict already exists
        existing_records = dbsession.query(RegRecord).filter_by(type=type,hrn=hrn).all()
        if existing_records:
            raise ExistingRecord(hrn)
           
        assert ('type' in record_dict)
        # returns the right type of RegRecord according to type in record
        record = make_record(dict=record_dict)
        record.just_created()
        record.authority = get_authority(record.hrn)
        auth_info = api.auth.get_auth_info(record.authority)
        pub_key = None
        # make sure record has a gid
        if not record.gid:
            uuid = create_uuid()
            pkey = Keypair(create=True)
            pub_key=getattr(record,'reg-keys',None)
            if pub_key is not None:
                # use only first key in record
                if pub_key and isinstance(pub_key, types.ListType): pub_key = pub_key[0]
                pkey = convert_public_key(pub_key)
    
            email=getattr(record,'email',None)
            gid_object = api.auth.hierarchy.create_gid(urn, uuid, pkey, email = email)
            gid = gid_object.save_to_string(save_parents=True)
            record.gid = gid
    
        if isinstance (record, RegAuthority):
            # update the tree
            if not api.auth.hierarchy.auth_exists(hrn):
                api.auth.hierarchy.create_auth(hrn_to_urn(hrn,'authority'))
    
            # get the GID from the newly created authority
            auth_info = api.auth.get_auth_info(hrn)
            gid = auth_info.get_gid_object()
            record.gid=gid.save_to_string(save_parents=True)

            # locate objects for relationships
            pi_hrns = getattr(record,'reg-pis',None)
            if pi_hrns is not None: record.update_pis (pi_hrns, dbsession)

        elif isinstance (record, RegSlice):
            researcher_hrns = getattr(record,'reg-researchers',None)
            if researcher_hrns is not None: record.update_researchers (researcher_hrns, dbsession)
        
        elif isinstance (record, RegUser):
            # create RegKey objects for incoming keys
            if hasattr(record,'reg-keys'):
                keys=getattr(record,'reg-keys')
                # some people send the key as a string instead of a list of strings
                if isinstance(keys,types.StringTypes): keys=[keys]
                logger.debug ("creating %d keys for user %s"%(len(keys),record.hrn))
                record.reg_keys = [ RegKey (key) for key in keys ]
            
        # update testbed-specific data if needed
        pointer = api.driver.register (record.__dict__, hrn, pub_key)

        record.pointer=pointer
        dbsession.add(record)
        dbsession.commit()
    
        # update membership for researchers, pis, owners, operators
        self.update_driver_relations (api, record, record)
        
        return record.get_gid_object().save_to_string(save_parents=True)
Exemple #14
0
    def Update(self, api, record_dict):
        dbsession = api.dbsession()
        assert ('type' in record_dict)
        new_record = make_record(dict=record_dict)
        (type, hrn) = (new_record.type, new_record.hrn)

        # make sure the record exists
        record = dbsession.query(RegRecord).filter_by(type=type,
                                                      hrn=hrn).first()
        if not record:
            raise RecordNotFound("hrn=%s, type=%s" % (hrn, type))
        record.just_updated()

        # Use the pointer from the existing record, not the one that the user
        # gave us. This prevents the user from inserting a forged pointer
        pointer = record.pointer

        # is there a change in keys ?
        new_key = None
        if type == 'user':
            if getattr(new_record, 'keys', None):
                new_key = new_record.keys
                if isinstance(new_key, types.ListType):
                    new_key = new_key[0]

        # take new_key into account
        if new_key:
            # update the openssl key and gid
            pkey = convert_public_key(new_key)
            uuid = create_uuid()
            urn = hrn_to_urn(hrn, type)
            gid_object = api.auth.hierarchy.create_gid(urn, uuid, pkey)
            gid = gid_object.save_to_string(save_parents=True)

        # xxx should do side effects from new_record to record
        # not too sure how to do that
        # not too big a deal with planetlab as the driver is authoritative, but...

        # update native relations
        if isinstance(record, RegSlice):
            researcher_hrns = getattr(new_record, 'researcher', None)
            if researcher_hrns is not None:
                record.update_researchers(researcher_hrns, dbsession)

        elif isinstance(record, RegAuthority):
            pi_hrns = getattr(new_record, 'pi', None)
            if pi_hrns is not None: record.update_pis(pi_hrns, dbsession)

        # update the PLC information that was specified with the record
        # xxx oddly enough, without this useless statement,
        # record.__dict__ as received by the driver seems to be off
        # anyway the driver should receive an object
        # (and then extract __dict__ itself if needed)
        print "DO NOT REMOVE ME before driver.update, record=%s" % record
        new_key_pointer = -1
        try:
            (pointer,
             new_key_pointer) = api.driver.update(record.__dict__,
                                                  new_record.__dict__, hrn,
                                                  new_key)
        except:
            pass
        if new_key and new_key_pointer:
            record.reg_keys = [RegKey(new_key, new_key_pointer)]
            record.gid = gid

        dbsession.commit()
        # update membership for researchers, pis, owners, operators
        self.update_driver_relations(api, record, new_record)

        return 1
Exemple #15
0
    def Register(self, api, record_dict):

        dbsession = api.dbsession()
        hrn, type = record_dict['hrn'], record_dict['type']
        urn = hrn_to_urn(hrn, type)
        # validate the type
        if type not in ['authority', 'slice', 'node', 'user']:
            raise UnknownSfaType(type)

        # check if record_dict already exists
        existing_records = dbsession.query(RegRecord).filter_by(type=type,
                                                                hrn=hrn).all()
        if existing_records:
            raise ExistingRecord(hrn)

        assert ('type' in record_dict)
        # returns the right type of RegRecord according to type in record
        record = make_record(dict=record_dict)
        record.just_created()
        record.authority = get_authority(record.hrn)
        auth_info = api.auth.get_auth_info(record.authority)
        pub_key = None
        # make sure record has a gid
        if not record.gid:
            uuid = create_uuid()
            pkey = Keypair(create=True)
            if getattr(record, 'keys', None):
                pub_key = record.keys
                # use only first key in record
                if isinstance(record.keys, types.ListType):
                    pub_key = record.keys[0]
                pkey = convert_public_key(pub_key)

            gid_object = api.auth.hierarchy.create_gid(urn, uuid, pkey)
            gid = gid_object.save_to_string(save_parents=True)
            record.gid = gid

        if isinstance(record, RegAuthority):
            # update the tree
            if not api.auth.hierarchy.auth_exists(hrn):
                api.auth.hierarchy.create_auth(hrn_to_urn(hrn, 'authority'))

            # get the GID from the newly created authority
            auth_info = api.auth.get_auth_info(hrn)
            gid = auth_info.get_gid_object()
            record.gid = gid.save_to_string(save_parents=True)

            # locate objects for relationships
            pi_hrns = getattr(record, 'pi', None)
            if pi_hrns is not None: record.update_pis(pi_hrns, dbsession)

        elif isinstance(record, RegSlice):
            researcher_hrns = getattr(record, 'researcher', None)
            if researcher_hrns is not None:
                record.update_researchers(researcher_hrns, dbsession)

        elif isinstance(record, RegUser):
            # create RegKey objects for incoming keys
            if hasattr(record, 'keys'):
                logger.debug("creating %d keys for user %s" %
                             (len(record.keys), record.hrn))
                record.reg_keys = [RegKey(key) for key in record.keys]

        # update testbed-specific data if needed
        pointer = api.driver.register(record.__dict__, hrn, pub_key)

        record.pointer = pointer
        dbsession.add(record)
        dbsession.commit()

        # update membership for researchers, pis, owners, operators
        self.update_driver_relations(api, record, record)

        return record.get_gid_object().save_to_string(save_parents=True)