Ejemplo n.º 1
0
    def __init__(self, db, seq):
	if not seq or type(seq) != type(""):
	    raise rhnException("First argument needs to be a sequence name", seq)
	self.__seq = seq
        if not isinstance(db, sql_base.Database):
            raise rhnException("Argument db is not a database instance", db)
        self.__db = db
Ejemplo n.º 2
0
    def select(self, row):
        if not type(row) == type({}) and not isinstance(row, UserDictCase):
            raise rhnException("Expecting hash argument. %s is invalid" % type(row),
                               row)
        if row == {}:
	    raise rhnException("The hash argument is empty", row)
        keys = row.keys()
        # Sort the list of keys, to always get the same list of arguments
        keys.sort()
        args = []
        for col in keys:
            if row[col] in (None, ''):
                clause = "%s is null" % col
            else:
                clause = "%s = :%s" % (col, col)
            args.append(clause)
	sql = "select * from %s where " % self.__table
	cursor = self.__db.prepare(sql + string.join(args, " and "))
	apply(cursor.execute, (), row)
	rows = cursor.fetchall_dict()
        if rows is None:
            return None
        # fill up the cache
        if self.__cache is not None:
            for row in rows:
                self.__cache[row[self.__hashid]] = row
        return map(lambda a: UserDictCase(a), rows)
Ejemplo n.º 3
0
def initDB(dsn=None, backend=None, host="localhost", port=None, username=None,
        password=None, database=None):
    """
    Initialize the database.

    For Oracle connections: provide just a string dsn argument, or a username,
    password, and database. (sid in this case)
    """

    if backend == None:
        backend=CFG.DB_BACKEND

    if not SUPPORTED_BACKENDS.has_key(backend):
        raise rhnException("Unsupported database backend", backend)

    if backend == ORACLE:
        # For Oracle, must provide either dsn or username, password,
        # and database.
        if not dsn and not (username and password and database):
            # Grab the default from the config file:
            dsn = CFG.DEFAULT_DB

        if dsn:
            # split the dsn up into username/pass/sid so we can call the rest of
            # the code in a uniform fashion for all database backends:
            (username, temp) = dsn.split("/")
            (password, database) = temp.split("@")

    if backend == POSTGRESQL:
        host = None
        port = None
        dsn = CFG.DEFAULT_DB
        (username, temp) = dsn.split("/")
        (password, dsn) = temp.split("@")
        for i in dsn.split(';'):
            (k, v) = i.split('=')
            if k == 'dbname':
                database = v
            elif k == 'host':
                host = v
            elif k == 'port':
                port = int(v)
            else:
                raise rhnException("Unknown piece in default_db string", i)

    # Hide the password
    add_to_seclist(dsn)
    try:
        __init__DB(backend, host, port, username, password, database)
#    except (rhnException, SQLError):
#        raise # pass on, we know those ones
#    except (KeyboardInterrupt, SystemExit):
#        raise
    except:
        raise
        #e_type, e_value = sys.exc_info()[:2]
        #raise rhnException("Could not initialize Oracle database connection",
        #                   str(e_type), str(e_value))
    return 0
Ejemplo n.º 4
0
 def __init__(self, db, table, hashid, cache = 0):
     if not table or not type(table) == type(""):
         raise rhnException("First argument needs to be a table name",
                            table)
     self.__table = table
     if not hashid or not type(hashid) == type(""):
         raise rhnException("Second argument needs to be the name of the unique index column",
                            hashid)
     self.__hashid = hashid
     if not isinstance(db, sql_base.Database):
         raise rhnException("Argument db is not a database instance", db)
     self.__db = db
     self.__cache = None
     if cache:
         self.__cache = {}
Ejemplo n.º 5
0
 def reload(self, server, reload_all = 0):
     log_debug(4, server, "reload_all = %d" % reload_all)
     
     if not self.server.load(int(server)):
         log_error("Could not find server record for reload", server)
         raise rhnFault(29, "Could not find server record in the database")
     self.cert = None
     # it is lame that we have to do this
     h = rhnSQL.prepare("""
     select label from rhnServerArch where id = :archid
     """)
     h.execute(archid = self.server["server_arch_id"])
     data = h.fetchone_dict()
     if not data:
         raise rhnException("Found server with invalid numeric "
                            "architecture reference",
                            self.server.data)
     self.archname = data['label']
     # we don't know this one anymore (well, we could look for, but
     # why would we do that?)
     self.user = None
     
     # XXX: Fix me
     if reload_all:
         if not self.reload_packages_byid(self.server["id"]) == 0:
             return -1
         if not self.reload_hardware_byid(self.server["id"]) == 0:
             return -1       
     return 0
Ejemplo n.º 6
0
    def _push_config_file(self, file):
        config_info_query = self._query_lookup_non_symlink_config_info
        if self._is_link(file) and file.get("symlink"):
            config_info_query = self._query_lookup_symlink_config_info

        # Look up the config info first
        h = rhnSQL.prepare(config_info_query)
        apply(h.execute, (), file)
        row = h.fetchone_dict()
        if not row:
            # Hmm
            raise rhnException("This query should always return a row")
        config_info_id = row['id']
        file['config_info_id'] = config_info_id

        # Look up the config file itself
        h = rhnSQL.prepare(self._query_lookup_config_file)
        apply(h.execute, (), file)
        row = h.fetchone_dict()
        if row:
            # Yay we already have this file
            # Later down the road, we're going to update modified for this
            # table
            file['config_file_id'] = row['id']
            return

        # Have to insert this config file, gotta use the api to keep quotas up2date...
        #h = rhnSQL.prepare(self._query_insert_config_file)
        #apply(h.execute, (), file)
        insert_call = rhnSQL.Function("rhn_config.insert_file",
            rhnSQL.types.NUMBER())
        file['config_file_id'] = insert_call(file['config_channel_id'], file['path'])
Ejemplo n.º 7
0
def update_kickstart_session(server_id, action_id, action_status, 
        kickstart_state, next_action_type):
    log_debug(3, server_id, action_id, action_status, kickstart_state, next_action_type)
    
    # Is this a kickstart-related action?
    ks_session_id = get_kickstart_session_id(server_id, action_id)
    if ks_session_id is None:
        # Nothing more to do
        log_debug(4, "Kickstart session not found")
        return None

    # Check the current action state
    if action_status == 2:
        # Completed
        ks_status = kickstart_state
        # Get the next action - it has to be of the right type
        next_action_id = get_next_action_id(action_id, next_action_type)
    elif action_status == 3:
        # Failed
        ks_status = 'failed'
        next_action_id = None
    else:
        raise rhnException("Invalid action state %s" % action_status)

    update_ks_session_table(ks_session_id, ks_status, next_action_id,
        server_id)
    return ks_session_id
Ejemplo n.º 8
0
 def check_password(self, password):
     good_pwd = str(self.contact["password"])
     old_pwd = str(self.contact["old_password"])
     if CFG.pam_auth_service:
         # a PAM service is defined
         # We have to check the user's rhnUserInfo.use_pam_authentication
         # XXX Should we create yet another __init_blah function? 
         # since it's the first time we had to lool at rhnUserInfo, 
         # I'll assume it's not something to happen very frequently, 
         # so I'll use a query for now
         # - misa
         # 
         h = rhnSQL.prepare("""
             select ui.use_pam_authentication
             from web_contact w, rhnUserInfo ui
             where w.login_uc = UPPER(:login)
             and w.id = ui.user_id""")
         h.execute(login=self.contact["login"])
         data = h.fetchone_dict()
         if not data:
             # This should not happen
             raise rhnException("No entry found for user %s" %
                 self.contact["login"])
         if data['use_pam_authentication'] == 'Y':
             # use PAM
             import rhnAuthPAM 
             return rhnAuthPAM.check_password(self.contact["login"], 
                 password, CFG.pam_auth_service)
         # If the entry in rhnUserInfo is 'N', perform regular
         # authentication
     return check_password(password, good_pwd, old_pwd)
Ejemplo n.º 9
0
def __create_server_group(group_label, org_id, maxnum = ''):
    # Add this new server to the pending group
    h = rhnSQL.prepare("""
    select sg.id, sg.current_members
    from rhnServerGroup sg
    where sg.group_type = ( select id from rhnServerGroupType
                            where label = :group_label )
    and sg.org_id = :org_id
    """)
    h.execute(org_id = org_id, group_label = group_label)
    data = h.fetchone_dict()
    if not data:
        # create the requested group
        ret_id = rhnSQL.Sequence("rhn_server_group_id_seq")()
        h = rhnSQL.prepare("""
        insert into rhnServerGroup
        ( id, name, description, max_members,
          group_type, org_id)
        select
            :new_id, sgt.name, sgt.name, :maxnum,
            sgt.id, :org_id
        from rhnServerGroupType sgt
        where sgt.label = :group_label
        """)
        rownum = h.execute(new_id = ret_id, org_id = org_id,
                  group_label = group_label, maxnum = str(maxnum))
        if rownum == 0:
            # No rows were created, probably invalid label
            raise rhnException("Could not create new group for org=`%s'"
                               % org_id, group_label)
    else:
        ret_id = data["id"]
    return ret_id
Ejemplo n.º 10
0
def get_kickstart_session_info(kickstart_session_id, server_id):
    h = rhnSQL.prepare(_query_get_kickstart_session_info)
    h.execute(kickstart_session_id=kickstart_session_id)
    row = h.fetchone_dict()
    if not row:
        raise rhnException("Could not fetch kickstart session id %s "
            "for server %s" % (kickstart_session_id, server_id))

    return row
Ejemplo n.º 11
0
def configure(serverId, actionId, dry_run=0):
    log_debug(3, dry_run)
    h = rhnSQL.prepare(_query_lookup_interval)
    h.execute(action_id=actionId)
    row = h.fetchone_dict()
    if not row:
        raise rhnException("rhnsd reconfig action scheduled, but no entries "
            "in rhnActionDaemonConfig found")
    # Format: (interval, restart)
    return (row['interval'], row['restart'])
Ejemplo n.º 12
0
    def insert(self, rows):
        # insert a single row into the table
        def insert_row(row, self = self):
            if self.__cache is not None:
                self.__cache[row[self.__hashid]] = row
            return self.__setitem__(None, row)
        if type(rows) == type({}) or isinstance(rows, UserDictCase):
            return insert_row(rows)
        if type(rows) == type([]):
            for x in rows:
                insert_row(x)
	    return None
        raise rhnException("Invalid data %s passed" % type(rows), rows)
Ejemplo n.º 13
0
    def reload(self, user_id):
        log_debug(3, user_id)

        # If we can not load these we have a fatal condition
        if not self.contact.load(user_id):
            raise rhnException("Could not find contact record for id", user_id)        
        if not self.customer.load(self.contact["org_id"]):
            raise rhnException("Could not find org record",
                               "user_id = %s" % user_id,
                               "org_id = %s" % self.contact["org_id"])        
        # These other ones are non fatal because we can create dummy records
        if not self.info.load(user_id):
            self.__init_info()           
        if not self.perms.load(user_id):
            self.__init_perms()       
        # The site info is trickier, we need to find it first
        if not self.site.load_sql("web_user_id = :userid and type = 'M'",
                                  { "userid" : user_id }):
            self.__init_site()
        # Fix the username
        self.username = self.contact['login']
        return 0
Ejemplo n.º 14
0
    def __init__(self, db, table, hashname, hashval = None):
        UserDictCase.__init__(self)
        if not isinstance(db, sql_base.Database):
            raise rhnException("Argument db is not a database instance", db)
        self.db = db              
        self.table = table
        self.hashname = string.lower(hashname)

        # and the data dictionary
        self.data = {}
        # is this a real entry (ie, use insert or update)
        self.real = 0
        if hashval is not None: # if we have to load an entry already...
            self.load(hashval)
Ejemplo n.º 15
0
    def handler(self, req):
        """ main Apache handler """
        log_debug(2)
        ret = apacheSession.handler(self, req)
        if ret != apache.OK:
            return ret

        if not CFG.SEND_MESSAGE_TO_ALL:
            # Need to get any string template overrides here, before any app
            # code gets executed, as the rhnFault error messages use the 
            # templates
            # If send_message_to_all, we don't have DB connectivity though
            h = rhnSQL.prepare("select label, value from rhnTemplateString")
            h.execute()
            
            templateStrings = {}
            while 1:
                row = h.fetchone_dict()
                if not row:
                    break

                templateStrings[row['label']] = row['value']
                
            if templateStrings:
                rhnFlags.set('templateOverrides', templateStrings)

            log_debug(4, "template strings:  %s" % templateStrings)

        if not CFG.SECRET_KEY:
            # Secret key not defined, complain loudly
            try:
                raise rhnException("Secret key not found!")
            except:
                rhnTB.Traceback(mail=1, req=req, severity="schema")
                req.status = 500
                req.send_http_header()
                return apache.OK

        
        # Try to authenticate the proxy if it this request passed
        # through a proxy.
        if self.proxyVersion:
            try:
                ret = self._req_processor.auth_proxy()
            except rhnFault, f:
                return self._req_processor.response(f.getxml())
Ejemplo n.º 16
0
    def _prepHandler(self):
        """ Handler part 0 """

        # Just to be on the safe side
        if self.req.main:
            # A subrequest
            return apache.DECLINE
        log_debug(4, rhnFlags.all())

        if not self.rhnParent:
            raise rhnException("Oops, no proxy parent! Exiting")

        # Copy the headers.
        rhnFlags.get('outputTransportOptions').clear()
        rhnFlags.get('outputTransportOptions').update(self._getHeaders(self.req))

        return apache.OK
Ejemplo n.º 17
0
def _check_token_limits(server_id, token_rec):
    token_id = token_rec["token_id"]   

    # Mark that we used this token
    server_used_token(server_id, token_id)
    
    # now check we're not using this token too much
    h = rhnSQL.prepare(_query_check_token_limits)
    h.execute(token_id = token_id)
    ret = h.fetchone_dict()
    if not ret:
        raise rhnException("Could not check usage limits for token",
                           server_id, token_rec)
    # See bug #79095: if usage_limit is NULL, it means unlimited reg tokens
    if ret["max_nr"] is not None and ret["max_nr"] < ret["curr_nr"]:
        log_error("Token usage limit exceeded", token_rec,
                  ret["max_nr"], server_id)
        raise rhnFault(61, _("Maximum usage count of %s reached") % ret["max_nr"])
    # all clean, we're below usage limits
    return 0
Ejemplo n.º 18
0
    def _validate_version(self, req):
        server_version = constants.PROTOCOL_VERSION
        vstr = "X-RHN-Satellite-XML-Dump-Version"
        if not req.headers_in.has_key(vstr):
            raise rhnFault(3010, "Missing version string")
        client_version = req.headers_in[vstr]

        # set the client version  through rhnFlags to access later
        rhnFlags.set("X-RHN-Satellite-XML-Dump-Version", client_version)

        log_debug(1, "Server version", server_version, "Client version", client_version)

        client_ver_arr = str(client_version).split(".")
        server_ver_arr = str(server_version).split(".")
        client_major = client_ver_arr[0]
        server_major = server_ver_arr[0]
        if len(client_ver_arr) >= 2:
            client_minor = client_ver_arr[1]
        else:
            client_minor = 0

        server_minor = server_ver_arr[1]

        try:
            client_major = int(client_major)
            client_minor = int(client_minor)
        except ValueError:
            raise rhnFault(3011, "Invalid version string %s" % client_version)

        try:
            server_major = int(server_major)
            server_minor = int(server_minor)
        except ValueError:
            raise rhnException("Invalid server version string %s" % server_version)

        if client_major != server_major:
            raise rhnFault(
                3012,
                "Client version %s does not match" " server version %s" % (client_version, server_version),
                explain=0,
            )
Ejemplo n.º 19
0
    def join_groups(self):
        """ For a new server, join server groups """

        # Sanity check - we should always have a user
        if not self.user:
            raise rhnException("User not specified")

        server_id = self.getid()
        user_id = self.user.getid()

        h = rhnSQL.prepare("""
            select system_group_id
            from rhnUserDefaultSystemGroups
            where user_id = :user_id
        """)
        h.execute(user_id=user_id)
        while 1:
            row = h.fetchone_dict()
            if not row:
                break
            server_group_id = row['system_group_id']
            log_debug(5, "Subscribing server to group %s" % server_group_id)

            server_lib.join_server_group(server_id, server_group_id)
Ejemplo n.º 20
0
            return None

    return resp

def check_password(username, password, service):
    global __username, __password
    auth = PAM.pam()
    auth.start(service, username, __pam_conv)

    # Save the username and passwords in the globals, the conversation
    # function needs access to them
    __username = username
    __password = password

    try:
        try:
            auth.authenticate()
            auth.acct_mgmt()
        finally:
            # Something to be always executed - cleanup
            __username = __password = None
    except PAM.error, e:
        resp, code = e.args[:2]
        log_error("Password check failed (%s): %s" % (code, resp))
        return 0
    except:
        raise rhnException('Internal PAM error')
    else:
        # Good password
        return 1
Ejemplo n.º 21
0
    def change_base_channel(self, new_rel):
        log_debug(3, self.server["id"], new_rel)
        old_rel = self.server["release"]       
        # test noops
        if old_rel == new_rel:
            return 1        
        current_channels = rhnChannel.channels_for_server(self.server["id"])
        # Extract the base channel off of 
        old_base = filter(lambda x: not x['parent_channel'], 
            current_channels)

        # Quick sanity check
        base_channels_count = len(old_base)
        if base_channels_count == 1:
            old_base = old_base[0]
        elif base_channels_count == 0:
            old_base = None
        else:
            raise rhnException("Server %s subscribed to multiple base channels"
                % (self.server["id"], ))
       
        #bz 442355
        #Leave custom base channels alone, don't alter any of the channel subscriptions
        if not CFG.RESET_BASE_CHANNEL and rhnChannel.isCustomChannel(old_base["id"]):
            log_debug(3, 
                    "Custom base channel detected, will not alter channel subscriptions")
            self.server["release"] = new_rel
            self.server.save()
            msg = """The Red Hat Network Update Agent has detected a 
            change in the base version of the operating system running 
            on your system, additionaly you are subscribed to a custom
            channel as your base channel.  Due to this configuration 
            your channel subscriptions will not be altered.
            """
            self.add_history("Updated system release from %s to %s" % (
                old_rel, new_rel), msg)
            self.save_history_byid(self.server["id"])
            return 1

        
        s = rhnChannel.LiteServer().init_from_server(self)
        s.release = new_rel
        s.arch = self.archname
        # Let get_server_channels deal with the errors and raise rhnFault
        target_channels = rhnChannel.guess_channels_for_server(s)
        target_base = filter(lambda x: not x['parent_channel'],
            target_channels)[0]

        channels_to_subscribe = []
        channels_to_unsubscribe = []
        if old_base and old_base['id'] == target_base['id']:
            # Same base channel. Preserve the currently subscribed child
            # channels, just add the ones that are missing
            hash = {}
            for c in current_channels:
                hash[c['id']] = c

            for c in target_channels:
                channel_id = c['id']
                if hash.has_key(channel_id):
                    # Already subscribed to this one
                    del hash[channel_id]
                    continue
                # Have to subscribe to this one
                channels_to_subscribe.append(c)

            # We don't want to lose subscriptions to prior channels, so don't
            # do anything with hash.values()
        else:
            # Different base channel
            channels_to_unsubscribe = current_channels
            channels_to_subscribe = target_channels

        rhnSQL.transaction("change_base_channel")
        self.server["release"] = new_rel
        self.server.save()
        if not (channels_to_subscribe or channels_to_unsubscribe):
            # Nothing to do, just add the history entry
            self.add_history("Updated system release from %s to %s" % (
                old_rel, new_rel))
            self.save_history_byid(self.server["id"])
            return 1

        # XXX: need a way to preserve existing subscriptions to
        # families so we can restore access to non-public ones.

        rhnChannel.unsubscribe_channels(self.server["id"],
            channels_to_unsubscribe)
        rhnChannel.subscribe_channels(self.server["id"],
            channels_to_subscribe)
        # now that we changed, recompute the errata cache for this one
        rhnSQL.Procedure("queue_server")(self.server["id"])
        # Make a history note
        sub_channels = rhnChannel.channels_for_server(self.server["id"])
        if sub_channels:
            channel_list = map(lambda a: a["name"], sub_channels)
            msg = """The Red Hat Network Update Agent has detected a 
            change in the base version of the operating system running 
            on your system and has updated your channel subscriptions
            to reflect that.
            Your server has been automatically subscribed to the following
            channels:\n%s\n""" % (string.join(channel_list, "\n"),)
        else:
            msg = """*** ERROR: ***
            While trying to subscribe this server to software channels:
            There are no channels serving release %s""" % new_rel
        self.add_history("Updated system release from %s to %s" % (
            old_rel, new_rel), msg)
        self.save_history_byid(self.server["id"])
        return 1
Ejemplo n.º 22
0
 def set_org_id(self, org_id):
     if not org_id:
         raise rhnException("Invalid org_id requested for user", org_id)
     self.contact["org_id"] = int(org_id)
     self.customer.load(int(org_id))
Ejemplo n.º 23
0
    def _push_contents(self, file):

        checksum_type = 'md5'       # FIXME: this should be configuration option

        file['file_size'] = 0
        file['is_binary'] = 'N'
        
        file_path = file.get('path')
        file_contents = file.get('file_contents') or ''

        if file.has_key('enc64') and file_contents:
            file_contents = base64.decodestring(file_contents)

	if not file.has_key('config_file_type_id'):
	    log_debug(4, "Client does not support config directories, so set file_type_id to 1")
            file['config_file_type_id'] = '1'

        file['checksum_type'] = checksum_type
        file['checksum'] = getStringChecksum(checksum_type, file_contents or '')

        if file_contents:
            file['file_size'] = len(file_contents)

            if file['file_size'] > self._get_maximum_file_size():
                raise ConfigFileTooLargeError(file_path, file['file_size'])

            # Is the content binary data?
            # XXX We may need a heuristic; this is what the web site does, and we
            # have to be consistent
            # XXX Yes this is iterating over a string
            for c in file_contents:
                if ord(c) > 127:
                    file['is_binary'] = 'Y'
                    break


        h = rhnSQL.prepare(self._query_content_lookup)
        apply(h.execute, (), file)
        row = h.fetchone_dict()

        if row:
            db_contents = rhnSQL.read_lob(row['contents']) or ''
            if file_contents == db_contents:
                # Same content
                file['config_content_id'] = row['id']
                log_debug(5, "same content")
                return

        # We have to insert a new file now
        content_seq = rhnSQL.Sequence('rhn_confcontent_id_seq')
        config_content_id = content_seq.next()
        file['config_content_id'] = config_content_id

        if file_contents:
            h = rhnSQL.prepare(self._query_insert_content)
        else:
            h = rhnSQL.prepare(self._query_insert_null_content)
            
        apply(h.execute, (), file)

        # Row should be there now
        h = rhnSQL.prepare(self._query_get_content_row)
        apply(h.execute, (), file)
        
        row = h.fetchone_dict()
        if not row:
            # Ouch
            raise rhnException("Row should have been inserted but it's not")


        if file_contents:
            log_debug(5, "writing file contents to blob")
            lob = row['contents']
            lob.write(file_contents)
Ejemplo n.º 24
0
    def __save(self):
        is_admin = 0
        if self.customer.real:
            # get the org_id and the applicant group id for this org
            org_id = self.customer["id"]
            h = rhnSQL.prepare("""
            select ug.id
            from rhnUserGroup ug, rhnUserGroupType ugt
            where ugt.label = 'org_applicant'
            and ug.group_type = ugt.id
            and ug.org_id = :org_id
            """)
            h.execute(org_id=org_id)
            data = h.fetchone_dict()
            # XXX: prone to errors, but we'll need to see them first
            grp_id = data["id"]
        else: # an org does not exist... create one
            create_new_org = rhnSQL.Procedure("create_new_org")
            ret = create_new_org(
                self.customer["name"],
                self.customer["password"],
                None, None, "B", 
                rhnSQL.types.NUMBER(),
                rhnSQL.types.NUMBER(),
                rhnSQL.types.NUMBER(),
            )
            org_id, adm_grp_id, app_grp_id = ret[-3:]
            # We want to make sure we set the group limits right
            tbl = rhnSQL.Row("rhnUserGroup", "id")
            # Set the default admin limits to Null
            tbl.load(adm_grp_id)
            # bz:210230: this value should default to Null
            tbl.save()
            # Set the default applicats limit to 0
            tbl.load(app_grp_id)
            tbl["max_members"] = 0
            tbl.save()
            # reload the customer table
            self.customer.load(org_id)
            # and finally, we put this one in the admin group
            grp_id = adm_grp_id
            is_admin = 1
            
        # save the contact
        if self.contact.real:
            if not self.contact["org_id"]:
                raise rhnException("Undefined org_id for existing user entry",
                                   self.contact.data)
            userid = self.contact["id"]
            self.contact.save()
        else:
            userid = self.getid()
            self.contact["org_id"] = org_id
            # if not admin, obfuscate the password
            # (and leave the old_password set)
            if not is_admin: # we only do this for new users.
                log_debug(5, "Obfuscating user password")
                user_pwd = self.contact["password"]
                crypt_pwd = crypt.crypt(user_pwd, str(userid)[-2:])
                self.contact["password"] = crypt_pwd
            self.contact.create(userid)
            # rhnUserInfo
            h = rhnSQL.prepare("insert into rhnUserInfo (user_id) "
                               "values (:user_id)")
            h.execute(user_id=userid)
            # now add this user to the admin/applicant group for his org
            create_ugm = rhnSQL.Procedure("rhn_user.add_to_usergroup")
            # grp_id is the admin or the applicant, depending on whether we
            # just created the org or not
            create_ugm(userid, grp_id)
            # and now reload this data
            self.contact.load(userid)
            
        # do the same for the other structures indexed by web_user_id
        # personal info
        if self.info.real:      self.info.save()
        else:                   self.info.create(userid) 
        # contact permissions
        if self.perms.real:     self.perms.save()
        else:                   self.perms.create(userid)
            
        # And now save the site information
        if self.site.real:
            siteid = self.site["id"]
            self.site.save()
        else:
            siteid = rhnSQL.Sequence("web_user_site_info_id_seq")()
            self.site["web_user_id"] = userid            
            self.site.create(siteid)

        return 0