Пример #1
0
static errno_t invalidate_entry(TALLOC_CTX *ctx,
                                struct sss_domain_info *domain,
                                const char *name, int entry_type)
{
    struct sysdb_attrs *sys_attrs = NULL;
    errno_t ret;

    sys_attrs = sysdb_new_attrs(ctx);
    if (sys_attrs) {
        ret = sysdb_attrs_add_time_t(sys_attrs,
                SYSDB_CACHE_EXPIRE, 1);
        if (ret == EOK) {
            switch (entry_type) {
                case TYPE_USER:
                    /* For users, we also need to reset the initgroups
                     * cache expiry */
                    ret = sysdb_attrs_add_time_t(sys_attrs,
                            SYSDB_INITGR_EXPIRE, 1);
                    if (ret != EOK) return ret;

                    ret = sysdb_set_user_attr(domain, name, sys_attrs,
                                              SYSDB_MOD_REP);
                    break;
                case TYPE_GROUP:
                    ret = sysdb_set_group_attr(domain, name, sys_attrs,
                                               SYSDB_MOD_REP);
                    break;
                case TYPE_NETGROUP:
                    ret = sysdb_set_netgroup_attr(domain, name, sys_attrs,
                                                  SYSDB_MOD_REP);
                    break;
                case TYPE_SERVICE:
                    ret = sysdb_set_service_attr(domain, name,
                                                 sys_attrs, SYSDB_MOD_REP);
                    break;
                case TYPE_AUTOFSMAP:
                    ret = sysdb_set_autofsmap_attr(domain, name,
                                                   sys_attrs, SYSDB_MOD_REP);
                    break;
                default:
                    return EINVAL;
            }
            if (ret != EOK) {
                DEBUG(SSSDBG_MINOR_FAILURE, "Could not set entry attributes\n");
            }
        } else {
            DEBUG(SSSDBG_MINOR_FAILURE,
                  "Could not add expiration time to attributes\n");
        }
        talloc_zfree(sys_attrs);
    } else {
        DEBUG(SSSDBG_MINOR_FAILURE, "Could not create sysdb attributes\n");
        ret = ENOMEM;
    }
    return ret;
}
Пример #2
0
static errno_t set_last_login(struct pam_auth_req *preq)
{
    struct sysdb_attrs *attrs;
    errno_t ret;

    attrs = sysdb_new_attrs(preq);
    if (!attrs) {
        ret = ENOMEM;
        goto fail;
    }

    ret = sysdb_attrs_add_time_t(attrs, SYSDB_LAST_ONLINE_AUTH, time(NULL));
    if (ret != EOK) {
        goto fail;
    }

    ret = sysdb_attrs_add_time_t(attrs, SYSDB_LAST_LOGIN, time(NULL));
    if (ret != EOK) {
        goto fail;
    }

    ret = sysdb_set_user_attr(preq->domain, preq->pd->user, attrs,
                              SYSDB_MOD_REP);
    if (ret != EOK) {
        DEBUG(SSSDBG_OP_FAILURE, "set_last_login failed.\n");
        preq->pd->pam_status = PAM_SYSTEM_ERR;
        goto fail;
    } else {
        preq->pd->last_auth_saved = true;
    }
    preq->callback(preq);

    return EOK;

fail:
    return ret;
}
Пример #3
0
static errno_t
sdap_save_native_sudorule(TALLOC_CTX *mem_ctx,
                          struct sysdb_ctx *sysdb_ctx,
                          struct sss_domain_info *domain,
                          struct sdap_attr_map *map,
                          struct sysdb_attrs *attrs,
                          int cache_timeout,
                          time_t now,
                          char **_usn)
{
    errno_t ret;
    const char *rule_name;

    ret = sysdb_attrs_get_string(attrs, map[SDAP_AT_SUDO_NAME].sys_name,
                                 &rule_name);
    if (ret == ERANGE) {
        DEBUG(SSSDBG_OP_FAILURE, ("Warning: found rule that contains none "
              "or multiple CN values. It will be skipped.\n"));
        return ret;
    } else if (ret != EOK) {
        DEBUG(SSSDBG_OP_FAILURE, ("Could not get rule name [%d]: %s\n",
              ret, strerror(ret)));
        return ret;
    }

    ret = sysdb_attrs_add_time_t(attrs, SYSDB_CACHE_EXPIRE,
                                 (cache_timeout ? (now + cache_timeout) : 0));
    if (ret) {
        DEBUG(SSSDBG_OP_FAILURE, ("Could not set sysdb cache expire [%d]: %s\n",
              ret, strerror(ret)));
        return ret;
    }

    ret = sdap_sudo_get_usn(mem_ctx, attrs, map, rule_name, _usn);
    if (ret != EOK) {
        DEBUG(SSSDBG_MINOR_FAILURE, ("Could not read USN from %s\n", rule_name));
        *_usn = NULL;
        /* but we will store the rule anyway */
    }

    ret = sysdb_save_sudorule(sysdb_ctx, domain, rule_name, attrs);
    if (ret != EOK) {
        DEBUG(SSSDBG_OP_FAILURE, ("Could not save sudorule %s\n", rule_name));
        return ret;
    }

    return ret;
}
Пример #4
0
errno_t
sysdb_update_ssh_known_host_expire(struct sysdb_ctx *sysdb,
                                   struct sss_domain_info *domain,
                                   const char *name,
                                   time_t now,
                                   int known_hosts_timeout)
{
    TALLOC_CTX *tmp_ctx;
    errno_t ret;
    struct sysdb_attrs *attrs;

    DEBUG(SSSDBG_TRACE_FUNC,
          ("Updating known_hosts expire time of host %s\n", name));

    tmp_ctx = talloc_new(NULL);
    if (!tmp_ctx) {
        return ENOMEM;
    }

    attrs = sysdb_new_attrs(tmp_ctx);
    if (!attrs) {
        ret = ENOMEM;
        goto done;
    }

    ret = sysdb_attrs_add_time_t(attrs, SYSDB_SSH_KNOWN_HOSTS_EXPIRE,
                                 now + known_hosts_timeout);
    if (ret != EOK) {
        DEBUG(SSSDBG_OP_FAILURE,
              ("Could not set known_hosts expire time [%d]: %s\n",
               ret, strerror(ret)));
        goto done;
    }

    ret = sysdb_update_ssh_host(sysdb, domain, name, attrs);
    if (ret != EOK) {
        goto done;
    }

    ret = EOK;

done:
    talloc_free(tmp_ctx);

    return ret;
}
Пример #5
0
errno_t
sysdb_store_service(struct sss_domain_info *domain,
                    const char *primary_name,
                    int port,
                    const char **aliases,
                    const char **protocols,
                    struct sysdb_attrs *extra_attrs,
                    char **remove_attrs,
                    uint64_t cache_timeout,
                    time_t now)
{
    errno_t ret;
    errno_t sret;
    TALLOC_CTX *tmp_ctx;
    bool in_transaction = false;
    struct ldb_result *res = NULL;
    const char *name;
    unsigned int i;
    struct ldb_dn *update_dn = NULL;
    struct sysdb_attrs *attrs;
    struct sysdb_ctx *sysdb;

    tmp_ctx = talloc_new(NULL);
    if (!tmp_ctx) return ENOMEM;

    sysdb = domain->sysdb;

    ret = sysdb_transaction_start(sysdb);
    if (ret != EOK) {
        DEBUG(SSSDBG_CRIT_FAILURE, "Failed to start transaction\n");
        goto done;
    }

    in_transaction = true;

    /* Check that the port is unique
     * If the port appears for any service other than
     * the one matching the primary_name, we need to
     * remove them so that getservbyport() can work
     * properly. Last entry saved to the cache should
     * always "win".
     */
    ret = sysdb_getservbyport(tmp_ctx, domain, port, NULL, &res);
    if (ret != EOK && ret != ENOENT) {
        goto done;
    } else if (ret != ENOENT) {
        if (res->count != 1) {
            /* Somehow the cache has multiple entries with
             * the same port. This is corrupted. We'll delete
             * them all to sort it out.
             */
            for (i = 0; i < res->count; i++) {
                DEBUG(SSSDBG_TRACE_FUNC,
                      "Corrupt cache entry [%s] detected. Deleting\n",
                       ldb_dn_canonical_string(tmp_ctx,
                                               res->msgs[i]->dn));

                ret = sysdb_delete_entry(sysdb, res->msgs[i]->dn, true);
                if (ret != EOK) {
                    DEBUG(SSSDBG_MINOR_FAILURE,
                          "Could not delete corrupt cache entry [%s]\n",
                           ldb_dn_canonical_string(tmp_ctx,
                                                   res->msgs[i]->dn));
                    goto done;
                }
            }
        } else {
            /* Check whether this is the same name as we're currently
             * saving to the cache.
             */
            name = ldb_msg_find_attr_as_string(res->msgs[0],
                                               SYSDB_NAME,
                                               NULL);
            if (!name || strcmp(name, primary_name) != 0) {

                if (!name) {
                    DEBUG(SSSDBG_CRIT_FAILURE,
                          "A service with no name?\n");
                    /* Corrupted */
                }

                /* Either this is a corrupt entry or it's another service
                 * claiming ownership of this port. In order to account
                 * for port reassignments, we need to delete the old entry.
                 */
                DEBUG(SSSDBG_TRACE_FUNC,
                      "Corrupt or replaced cache entry [%s] detected. "
                       "Deleting\n",
                       ldb_dn_canonical_string(tmp_ctx,
                                               res->msgs[0]->dn));

                ret = sysdb_delete_entry(sysdb, res->msgs[0]->dn, true);
                if (ret != EOK) {
                    DEBUG(SSSDBG_MINOR_FAILURE,
                          "Could not delete cache entry [%s]\n",
                           ldb_dn_canonical_string(tmp_ctx,
                                                   res->msgs[0]->dn));
                }
            }
        }
    }
    talloc_zfree(res);

    /* Ok, ports should now be unique. Now look
     * the service up by name to determine if we
     * need to update existing entries or modify
     * aliases.
     */
    ret = sysdb_getservbyname(tmp_ctx, domain, primary_name, NULL, &res);
    if (ret != EOK && ret != ENOENT) {
        goto done;
    } else if (ret != ENOENT) { /* Found entries */
        for (i = 0; i < res->count; i++) {
            /* Check whether this is the same name as we're currently
             * saving to the cache.
             */
            name = ldb_msg_find_attr_as_string(res->msgs[i],
                                               SYSDB_NAME,
                                               NULL);
            if (!name) {

                /* Corrupted */
                DEBUG(SSSDBG_CRIT_FAILURE,
                      "A service with no name?\n");
                DEBUG(SSSDBG_TRACE_FUNC,
                      "Corrupt cache entry [%s] detected. Deleting\n",
                       ldb_dn_canonical_string(tmp_ctx,
                                               res->msgs[i]->dn));

                ret = sysdb_delete_entry(sysdb, res->msgs[i]->dn, true);
                if (ret != EOK) {
                    DEBUG(SSSDBG_MINOR_FAILURE,
                          "Could not delete corrupt cache entry [%s]\n",
                           ldb_dn_canonical_string(tmp_ctx,
                                                   res->msgs[i]->dn));
                    goto done;
                }
            } else if (strcmp(name, primary_name) == 0) {
                /* This is the same service name, so we need
                 * to update this entry with the values
                 * provided.
                 */
                if(update_dn) {
                    DEBUG(SSSDBG_CRIT_FAILURE,
                          "Two existing services with the same name: [%s]? "
                           "Deleting both.\n",
                           primary_name);

                    /* Delete the entry from the previous pass */
                    ret = sysdb_delete_entry(sysdb, update_dn, true);
                    if (ret != EOK) {
                        DEBUG(SSSDBG_MINOR_FAILURE,
                              "Could not delete cache entry [%s]\n",
                               ldb_dn_canonical_string(tmp_ctx,
                                                       update_dn));
                        goto done;
                    }

                    /* Delete the new entry as well */
                    ret = sysdb_delete_entry(sysdb, res->msgs[i]->dn, true);
                    if (ret != EOK) {
                        DEBUG(SSSDBG_MINOR_FAILURE,
                              "Could not delete cache entry [%s]\n",
                               ldb_dn_canonical_string(tmp_ctx,
                                                       res->msgs[i]->dn));
                        goto done;
                    }

                    update_dn = NULL;
                } else {
                    update_dn = talloc_steal(tmp_ctx, res->msgs[i]->dn);
                }
            } else {
                /* Another service is claiming this name as an alias.
                 * In order to account for aliases being promoted to
                 * primary names, we need to make sure to remove the
                 * old alias entry.
                 */
                ret = sysdb_svc_remove_alias(sysdb,
                                             res->msgs[i]->dn,
                                             primary_name);
                if (ret != EOK) goto done;
            }
        }
        talloc_zfree(res);
    }

    if (update_dn) {
        /* Update the existing entry */
        ret = sysdb_svc_update(sysdb, update_dn, port, aliases, protocols);
    } else {
        /* Add a new entry */
        ret = sysdb_svc_add(tmp_ctx, domain, primary_name, port,
                            aliases, protocols, &update_dn);
    }
    if (ret != EOK) goto done;

    /* Set the cache timeout */
    if (!extra_attrs) {
        attrs = sysdb_new_attrs(tmp_ctx);
        if (!attrs) {
            ret = ENOMEM;
            goto done;
        }
    } else {
        attrs = extra_attrs;
    }

    ret = sysdb_attrs_add_time_t(attrs, SYSDB_LAST_UPDATE, now);
    if (ret) goto done;

    ret = sysdb_attrs_add_time_t(attrs, SYSDB_CACHE_EXPIRE,
                                 ((cache_timeout) ?
                                  (now + cache_timeout) : 0));
    if (ret) goto done;

    ret = sysdb_set_entry_attr(sysdb, update_dn, attrs, SYSDB_MOD_REP);
    if (ret != EOK) goto done;

    if (remove_attrs) {
        ret = sysdb_remove_attrs(domain, primary_name,
                                 SYSDB_MEMBER_SERVICE,
                                 remove_attrs);
        if (ret != EOK) {
            DEBUG(SSSDBG_MINOR_FAILURE,
                  "Could not remove missing attributes: [%s]\n",
                   strerror(ret));
            goto done;
        }
    }

    ret = sysdb_transaction_commit(sysdb);
    if (ret != EOK) {
        DEBUG(SSSDBG_CRIT_FAILURE, "Failed to commit transaction\n");
        goto done;
    }
    in_transaction = false;

done:
    if (in_transaction) {
        sret = sysdb_transaction_cancel(sysdb);
        if (sret != EOK) {
            DEBUG(SSSDBG_CRIT_FAILURE, "Could not cancel transaction\n");
        }
    }
    talloc_free(tmp_ctx);
    return ret;
}
Пример #6
0
errno_t
sysdb_store_ssh_host(struct sysdb_ctx *sysdb,
                     struct sss_domain_info *domain,
                     const char *name,
                     const char *alias,
                     time_t now,
                     struct sysdb_attrs *attrs)
{
    TALLOC_CTX *tmp_ctx;
    errno_t ret, sret;
    bool in_transaction = false;
    const char *search_attrs[] = { SYSDB_NAME_ALIAS, NULL };
    bool new_alias;
    struct ldb_message *host = NULL;
    struct ldb_message_element *el;
    unsigned int i;

    DEBUG(SSSDBG_TRACE_FUNC, ("Storing host %s\n", name));

    tmp_ctx = talloc_new(NULL);
    if (!tmp_ctx) {
        return ENOMEM;
    }

    ret = sysdb_transaction_start(sysdb);
    if (ret != EOK) {
        DEBUG(SSSDBG_CRIT_FAILURE, ("Failed to start transaction\n"));
        goto done;
    }

    in_transaction = true;

    ret = sysdb_get_ssh_host(tmp_ctx, sysdb, domain, name, search_attrs, &host);
    if (ret != EOK && ret != ENOENT) {
        goto done;
    }

    ret = sysdb_attrs_add_string(attrs, SYSDB_OBJECTCLASS, SYSDB_SSH_HOST_OC);
    if (ret != EOK) {
        DEBUG(SSSDBG_OP_FAILURE,
              ("Could not set object class [%d]: %s\n", ret, strerror(ret)));
        goto done;
    }

    ret = sysdb_attrs_add_string(attrs, SYSDB_NAME, name);
    if (ret != EOK) {
        DEBUG(SSSDBG_OP_FAILURE,
              ("Could not set name attribute [%d]: %s\n", ret, strerror(ret)));
        goto done;
    }

    if (alias) {
        new_alias = true;

        /* copy aliases from the existing entry */
        if (host) {
            el = ldb_msg_find_element(host, SYSDB_NAME_ALIAS);

            if (el) {
                for (i = 0; i < el->num_values; i++) {
                    if (strcmp((char *)el->values[i].data, alias) == 0) {
                        new_alias = false;
                    }

                    ret = sysdb_attrs_add_val(attrs,
                                              SYSDB_NAME_ALIAS, &el->values[i]);
                    if (ret != EOK) {
                        DEBUG(SSSDBG_OP_FAILURE,
                              ("Could not add name alias %s [%d]: %s\n",
                               el->values[i].data, ret, strerror(ret)));
                        goto done;
                    }
                }
            }
        }

        /* add alias only if it is not already present */
        if (new_alias) {
            ret = sysdb_attrs_add_string(attrs, SYSDB_NAME_ALIAS, alias);
            if (ret != EOK) {
                DEBUG(SSSDBG_OP_FAILURE,
                      ("Could not add name alias %s [%d]: %s\n",
                       alias, ret, strerror(ret)));
                goto done;
            }
        }
    }

    /* make sure sshPublicKey is present when modifying an existing host */
    if (host) {
        ret = sysdb_attrs_get_el(attrs, SYSDB_SSH_PUBKEY, &el);
        if (ret != EOK) {
            DEBUG(SSSDBG_OP_FAILURE,
                  ("Could not get sysdb sshPublicKey [%d]: %s\n",
                   ret, strerror(ret)));
            goto done;
        }
    }

    ret = sysdb_attrs_add_time_t(attrs, SYSDB_LAST_UPDATE, now);
    if (ret != EOK) {
        DEBUG(SSSDBG_OP_FAILURE,
              ("Could not set sysdb lastUpdate [%d]: %s\n",
               ret, strerror(ret)));
        goto done;
    }

    ret = sysdb_update_ssh_host(sysdb, domain, name, attrs);
    if (ret != EOK) {
        goto done;
    }

    ret = sysdb_transaction_commit(sysdb);
    if (ret != EOK) {
        DEBUG(SSSDBG_CRIT_FAILURE, ("Failed to commit transaction\n"));
        goto done;
    }

    in_transaction = false;

    ret = EOK;

done:
    if (in_transaction) {
        sret = sysdb_transaction_cancel(sysdb);
        if (sret != EOK) {
            DEBUG(SSSDBG_CRIT_FAILURE, ("Could not cancel transaction\n"));
        }
    }

    talloc_free(tmp_ctx);

    return ret;
}
Пример #7
0
/* FIXME: support storing additional attributes */
int sdap_save_user(TALLOC_CTX *memctx,
                   struct sysdb_ctx *ctx,
                   struct sdap_options *opts,
                   struct sss_domain_info *dom,
                   struct sysdb_attrs *attrs,
                   bool is_initgr,
                   char **_usn_value,
                   time_t now)
{
    struct ldb_message_element *el;
    int ret;
    const char *name = NULL;
    const char *fullname = NULL;
    const char *pwd;
    const char *gecos;
    const char *homedir;
    const char *shell;
    const char *orig_dn = NULL;
    uid_t uid;
    gid_t gid, primary_gid;
    struct sysdb_attrs *user_attrs;
    char *upn = NULL;
    size_t i;
    int cache_timeout;
    char *usn_value = NULL;
    char **missing = NULL;
    TALLOC_CTX *tmpctx = NULL;
    bool use_id_mapping = dp_opt_get_bool(opts->basic, SDAP_ID_MAPPING);
    char *sid_str;
    char *dom_sid_str = NULL;
    char *group_sid_str;

    DEBUG(9, ("Save user\n"));

    tmpctx = talloc_new(NULL);
    if (!tmpctx) {
        ret = ENOMEM;
        goto done;
    }

    user_attrs = sysdb_new_attrs(tmpctx);
    if (user_attrs == NULL) {
        ret = ENOMEM;
        goto done;
    }

    ret = sysdb_attrs_primary_name(ctx, attrs,
                                   opts->user_map[SDAP_AT_USER_NAME].name,
                                   &name);
    if (ret != EOK) {
        DEBUG(1, ("Failed to save the user - entry has no name attribute\n"));
        goto done;
    }

    if (opts->schema_type == SDAP_SCHEMA_AD) {
        ret = sysdb_attrs_get_string(attrs,
                    opts->user_map[SDAP_AT_USER_FULLNAME].sys_name, &fullname);
        if (ret == EOK) {
            ret = sysdb_attrs_add_string(user_attrs, SYSDB_FULLNAME, fullname);
            if (ret != EOK) {
                goto done;
            }
        } else if (ret != ENOENT) {
            goto done;
        }
    }

    ret = sysdb_attrs_get_el(attrs,
                             opts->user_map[SDAP_AT_USER_PWD].sys_name, &el);
    if (ret) goto done;
    if (el->num_values == 0) pwd = NULL;
    else pwd = (const char *)el->values[0].data;

    ret = sysdb_attrs_get_el(attrs,
                             opts->user_map[SDAP_AT_USER_GECOS].sys_name, &el);
    if (ret) goto done;
    if (el->num_values == 0) gecos = NULL;
    else gecos = (const char *)el->values[0].data;

    if (!gecos) {
        /* Fall back to the user's full name */
        ret = sysdb_attrs_get_el(
                attrs,
                opts->user_map[SDAP_AT_USER_FULLNAME].sys_name, &el);
        if (ret) goto done;
        if (el->num_values > 0) gecos = (const char *)el->values[0].data;
    }

    ret = sysdb_attrs_get_el(attrs,
                             opts->user_map[SDAP_AT_USER_HOME].sys_name, &el);
    if (ret) goto done;
    if (el->num_values == 0) homedir = NULL;
    else homedir = (const char *)el->values[0].data;

    ret = sysdb_attrs_get_el(attrs,
                             opts->user_map[SDAP_AT_USER_SHELL].sys_name, &el);
    if (ret) goto done;
    if (el->num_values == 0) shell = NULL;
    else shell = (const char *)el->values[0].data;

    /* Retrieve or map the UID as appropriate */
    if (use_id_mapping) {
        DEBUG(SSSDBG_TRACE_LIBS,
              ("Mapping user [%s] objectSID to unix ID\n", name));

        ret = sdap_attrs_get_sid_str(
                tmpctx, opts->idmap_ctx, attrs,
                opts->user_map[SDAP_AT_USER_OBJECTSID].sys_name,
                &sid_str);
        if (ret != EOK) goto done;

        /* Add string representation to the cache for easier
         * debugging
         */
        ret = sysdb_attrs_add_string(user_attrs, SYSDB_SID_STR, sid_str);
        if (ret != EOK) goto done;

        /* Convert the SID into a UNIX user ID */
        ret = sdap_idmap_sid_to_unix(opts->idmap_ctx, sid_str, &uid);
        if (ret == ENOTSUP) {
            DEBUG(SSSDBG_TRACE_FUNC, ("Skipping built-in object.\n"));
            ret = EOK;
            goto done;
        } else if (ret != EOK) {
            goto done;
        }

        /* Store the UID in the ldap_attrs so it doesn't get
         * treated as a missing attribute from LDAP and removed.
         */
        ret = sdap_replace_id(attrs, SYSDB_UIDNUM, uid);
        if (ret) {
            DEBUG(SSSDBG_OP_FAILURE, ("Cannot set the id-mapped UID\n"));
            goto done;
        }
    } else {
        ret = sysdb_attrs_get_uint32_t(attrs,
                                       opts->user_map[SDAP_AT_USER_UID].sys_name,
                                       &uid);
        if (ret != EOK) {
            DEBUG(1, ("no uid provided for [%s] in domain [%s].\n",
                      name, dom->name));
            ret = EINVAL;
            goto done;
        }
    }
    /* check that the uid is valid for this domain */
    if (OUT_OF_ID_RANGE(uid, dom->id_min, dom->id_max)) {
            DEBUG(2, ("User [%s] filtered out! (uid out of range)\n",
                      name));
        ret = EINVAL;
        goto done;
    }

    if (use_id_mapping) {
        ret = sysdb_attrs_get_uint32_t(
                attrs,
                opts->user_map[SDAP_AT_USER_PRIMARY_GROUP].sys_name,
                &primary_gid);
        if (ret != EOK) {
            DEBUG(SSSDBG_MINOR_FAILURE,
                  ("no primary group ID provided for [%s] in domain [%s].\n",
                   name, dom->name));
            ret = EINVAL;
            goto done;
        }

        /* The primary group ID is just the RID part of the objectSID
         * of the group. Generate the GID by adding this to the domain
         * SID value.
         */

        /* First, get the domain SID if we didn't do so above */
        if (!dom_sid_str) {
            ret = sdap_idmap_get_dom_sid_from_object(tmpctx, sid_str,
                                                     &dom_sid_str);
            if (ret != EOK) {
                DEBUG(SSSDBG_MINOR_FAILURE,
                      ("Could not parse domain SID from [%s]\n", sid_str));
                goto done;
            }
        }

        /* Add the RID to the end */
        group_sid_str = talloc_asprintf(tmpctx, "%s-%lu",
                                        dom_sid_str,
                                        (unsigned long)primary_gid);
        if (!group_sid_str) {
            ret = ENOMEM;
            goto done;
        }

        /* Convert the SID into a UNIX group ID */
        ret = sdap_idmap_sid_to_unix(opts->idmap_ctx, group_sid_str, &gid);
        if (ret != EOK) goto done;

        /* Store the GID in the ldap_attrs so it doesn't get
         * treated as a missing attribute from LDAP and removed.
         */
        ret = sysdb_attrs_add_uint32(attrs, SYSDB_GIDNUM, gid);
        if (ret != EOK) goto done;
    } else {
        ret = sysdb_attrs_get_uint32_t(attrs,
                                       opts->user_map[SDAP_AT_USER_GID].sys_name,
                                       &gid);
        if (ret != EOK) {
            DEBUG(1, ("no gid provided for [%s] in domain [%s].\n",
                      name, dom->name));
            ret = EINVAL;
            goto done;
        }
    }

    /* check that the gid is valid for this domain */
    if (OUT_OF_ID_RANGE(gid, dom->id_min, dom->id_max)) {
            DEBUG(2, ("User [%s] filtered out! (primary gid out of range)\n",
                      name));
        ret = EINVAL;
        goto done;
    }

    ret = sysdb_attrs_get_el(attrs, SYSDB_ORIG_DN, &el);
    if (ret) {
        goto done;
    }
    if (!el || el->num_values == 0) {
        DEBUG(SSSDBG_MINOR_FAILURE,
              ("originalDN is not available for [%s].\n", name));
    } else {
        orig_dn = (const char *) el->values[0].data;
        DEBUG(SSSDBG_TRACE_INTERNAL, ("Adding originalDN [%s] to attributes "
                "of [%s].\n", orig_dn, name));

        ret = sysdb_attrs_add_string(user_attrs, SYSDB_ORIG_DN, orig_dn);
        if (ret) {
            goto done;
        }
    }

    ret = sysdb_attrs_get_el(attrs, SYSDB_MEMBEROF, &el);
    if (ret) {
        goto done;
    }
    if (el->num_values == 0) {
        DEBUG(7, ("Original memberOf is not available for [%s].\n",
                    name));
    } else {
        DEBUG(7, ("Adding original memberOf attributes to [%s].\n",
                    name));
        for (i = 0; i < el->num_values; i++) {
            ret = sysdb_attrs_add_string(user_attrs, SYSDB_ORIG_MEMBEROF,
                    (const char *) el->values[i].data);
            if (ret) {
                goto done;
            }
        }
    }

    ret = sdap_attrs_add_string(attrs,
                            opts->user_map[SDAP_AT_USER_MODSTAMP].sys_name,
                            "original mod-Timestamp",
                            name, user_attrs);
    if (ret != EOK) {
        goto done;
    }

    ret = sysdb_attrs_get_el(attrs,
                      opts->user_map[SDAP_AT_USER_USN].sys_name, &el);
    if (ret) {
        goto done;
    }
    if (el->num_values == 0) {
        DEBUG(7, ("Original USN value is not available for [%s].\n",
                  name));
    } else {
        ret = sysdb_attrs_add_string(user_attrs,
                          opts->user_map[SDAP_AT_USER_USN].sys_name,
                          (const char*)el->values[0].data);
        if (ret) {
            goto done;
        }
        usn_value = talloc_strdup(tmpctx, (const char*)el->values[0].data);
        if (!usn_value) {
            ret = ENOMEM;
            goto done;
        }
    }

    ret = sysdb_attrs_get_el(attrs,
                             opts->user_map[SDAP_AT_USER_PRINC].sys_name, &el);
    if (ret) {
        goto done;
    }
    if (el->num_values == 0) {
        DEBUG(7, ("User principal is not available for [%s].\n", name));
    } else {
        upn = talloc_strdup(user_attrs, (const char*) el->values[0].data);
        if (!upn) {
            ret = ENOMEM;
            goto done;
        }
        if (dp_opt_get_bool(opts->basic, SDAP_FORCE_UPPER_CASE_REALM)) {
            make_realm_upper_case(upn);
        }
        DEBUG(7, ("Adding user principal [%s] to attributes of [%s].\n",
                  upn, name));
        ret = sysdb_attrs_add_string(user_attrs, SYSDB_UPN, upn);
        if (ret) {
            goto done;
        }
    }

    for (i = SDAP_FIRST_EXTRA_USER_AT; i < SDAP_OPTS_USER; i++) {
        ret = sdap_attrs_add_list(attrs, opts->user_map[i].sys_name,
                                  NULL, name, user_attrs);
        if (ret) {
            goto done;
        }
    }

    cache_timeout = dom->user_timeout;

    if (is_initgr) {
        ret = sysdb_attrs_add_time_t(user_attrs, SYSDB_INITGR_EXPIRE,
                                     (cache_timeout ?
                                      (time(NULL) + cache_timeout) : 0));
        if (ret) {
            goto done;
        }
    }

    ret = sdap_save_all_names(name, attrs, !dom->case_sensitive, user_attrs);
    if (ret != EOK) {
        DEBUG(1, ("Failed to save user names\n"));
        goto done;
    }

    /* Make sure that any attributes we requested from LDAP that we
     * did not receive are also removed from the sysdb
     */
    ret = list_missing_attrs(user_attrs, opts->user_map, SDAP_OPTS_USER,
                             attrs, &missing);
    if (ret != EOK) {
        goto done;
    }

    DEBUG(6, ("Storing info for user %s\n", name));

    ret = sysdb_store_user(ctx, dom, name, pwd, uid, gid,
                           gecos, homedir, shell, orig_dn,
                           user_attrs, missing, cache_timeout, now);
    if (ret) goto done;

    if (_usn_value) {
        *_usn_value = talloc_steal(memctx, usn_value);
    }

    talloc_steal(memctx, user_attrs);
    ret = EOK;

done:
    if (ret) {
        DEBUG(2, ("Failed to save user [%s]\n",
                  name ? name : "Unknown"));
    }
    talloc_free(tmpctx);
    return ret;
}
Пример #8
0
errno_t
sysdb_invalidate_autofs_maps(struct sysdb_ctx *sysdb,
                             struct sss_domain_info *domain)
{
    errno_t ret;
    TALLOC_CTX *tmp_ctx;
    const char *filter;
    struct sysdb_attrs *sys_attrs = NULL;
    const char *attrs[] = { SYSDB_OBJECTCLASS,
                            SYSDB_NAME,
                            SYSDB_CACHE_EXPIRE,
                            NULL };
    size_t count;
    struct ldb_message **msgs;
    const char *name;
    bool in_transaction = false;
    int sret;
    int i;

    tmp_ctx = talloc_new(NULL);
    if (!tmp_ctx) return ENOMEM;

    filter = talloc_asprintf(tmp_ctx, "(&(objectclass=%s)(%s=*))",
                             SYSDB_AUTOFS_MAP_OC, SYSDB_NAME);
    if (!filter) {
        ret = ENOMEM;
        goto done;
    }

    ret = sysdb_search_custom(tmp_ctx, sysdb, domain, filter,
                              AUTOFS_MAP_SUBDIR, attrs,
                              &count, &msgs);
    if (ret != EOK && ret != ENOENT) {
        DEBUG(SSSDBG_CRIT_FAILURE,
              ("Error looking up autofs maps"));
        goto done;
    } else if (ret == ENOENT) {
        ret = EOK;
        goto done;
    }

    sys_attrs = sysdb_new_attrs(tmp_ctx);
    if (!sys_attrs) {
        ret = ENOMEM;
        goto done;
    }

    ret = sysdb_attrs_add_time_t(sys_attrs, SYSDB_CACHE_EXPIRE, 1);
    if (ret != EOK) {
        goto done;
    }

    ret = sysdb_transaction_start(sysdb);
    if (ret != EOK) {
        DEBUG(SSSDBG_CRIT_FAILURE, ("Failed to start transaction\n"));
        goto done;
    }
    in_transaction = true;

    for (i = 0; i < count; i++) {
        name = ldb_msg_find_attr_as_string(msgs[i], SYSDB_NAME, NULL);
        if (!name) {
            DEBUG(SSSDBG_MINOR_FAILURE, ("A map with no name?\n"));
            continue;
        }

        ret = sysdb_set_autofsmap_attr(sysdb, domain, name,
                                       sys_attrs, SYSDB_MOD_REP);
        if (ret != EOK) {
            DEBUG(SSSDBG_MINOR_FAILURE, ("Could not expire map %s\n", name));
            continue;
        }
    }

    ret = sysdb_transaction_commit(sysdb);
    if (ret != EOK) {
        DEBUG(SSSDBG_OP_FAILURE, ("Could not commit transaction\n"));
        goto done;
    }
    in_transaction = false;

    ret = EOK;
done:
    if (in_transaction) {
        sret = sysdb_transaction_cancel(sysdb);
        if (sret != EOK) {
            DEBUG(SSSDBG_OP_FAILURE, ("Could not cancel transaction\n"));
        }
    }
    talloc_free(tmp_ctx);
    return ret;
}
Пример #9
0
errno_t
sysdb_save_autofsmap(struct sysdb_ctx *sysdb_ctx,
                     struct sss_domain_info *domain,
                     const char *name,
                     const char *autofsmapname,
                     struct sysdb_attrs *attrs,
                     int cache_timeout,
                     time_t now)
{
    errno_t ret;
    TALLOC_CTX *tmp_ctx;

    DEBUG(SSSDBG_TRACE_FUNC, ("Adding autofs map %s\n", autofsmapname));

    tmp_ctx = talloc_new(NULL);
    if (!tmp_ctx) {
        return ENOMEM;
    }

    if (!attrs) {
        attrs = sysdb_new_attrs(tmp_ctx);
        if (!attrs) {
            ret = ENOMEM;
            goto done;
        }
    }

    ret = sysdb_attrs_add_string(attrs, SYSDB_OBJECTCLASS,
                                 SYSDB_AUTOFS_MAP_OC);
    if (ret != EOK) {
        DEBUG(SSSDBG_OP_FAILURE, ("Could not set map object class [%d]: %s\n",
              ret, strerror(ret)));
        goto done;
    }

    ret = sysdb_attrs_add_string(attrs, SYSDB_AUTOFS_MAP_NAME, autofsmapname);
    if (ret != EOK) {
        DEBUG(SSSDBG_OP_FAILURE, ("Could not set map name [%d]: %s\n",
              ret, strerror(ret)));
        goto done;
    }

    ret = sysdb_attrs_add_string(attrs, SYSDB_NAME, name);
    if (ret != EOK) {
        DEBUG(SSSDBG_OP_FAILURE, ("Could not set name attribute [%d]: %s\n",
              ret, strerror(ret)));
        goto done;
    }

    ret = sysdb_attrs_add_time_t(attrs, SYSDB_LAST_UPDATE, now);
    if (ret) {
        DEBUG(SSSDBG_OP_FAILURE, ("Could not set sysdb lastUpdate [%d]: %s\n",
              ret, strerror(ret)));
        goto done;
    }

    ret = sysdb_attrs_add_time_t(attrs, SYSDB_CACHE_EXPIRE,
                                 ((cache_timeout) ?
                                  (now + cache_timeout) : 0));
    if (ret) {
        DEBUG(SSSDBG_OP_FAILURE, ("Could not set sysdb cache expire [%d]: %s\n",
              ret, strerror(ret)));
        goto done;
    }

    ret = sysdb_store_custom(sysdb_ctx, domain, name, AUTOFS_MAP_SUBDIR, attrs);
    if (ret != EOK) {
        DEBUG(SSSDBG_OP_FAILURE, ("sysdb_store_custom failed [%d]: %s\n",
              ret, strerror(ret)));
        goto done;
    }

    ret = EOK;
done:
    talloc_free(tmp_ctx);
    return ret;
}