Example #1
0
/*
  convert a dom_sid to a string
*/
char *dom_sid_string(TALLOC_CTX *mem_ctx, const struct dom_sid *sid)
{
	char buf[DOM_SID_STR_BUFLEN];
	char *result;
	int len;

	len = dom_sid_string_buf(sid, buf, sizeof(buf));

	if (len+1 > sizeof(buf)) {
		return talloc_strdup(mem_ctx, "(SID ERR)");
	}

	/*
	 * Avoid calling strlen (via talloc_strdup), we already have
	 * the length
	 */
	result = (char *)talloc_memdup(mem_ctx, buf, len+1);
	if (result == NULL) {
		return NULL;
	}

	/*
	 * beautify the talloc_report output
	 */
	talloc_set_name_const(result, result);
	return result;
}
static char *group_mapping_key(TALLOC_CTX *mem_ctx, const struct dom_sid *sid)
{
	char sidstr[DOM_SID_STR_BUFLEN];
	int len;

	len = dom_sid_string_buf(sid, sidstr, sizeof(sidstr));
	if (len >= sizeof(sidstr)) {
		return NULL;
	}

	return talloc_asprintf(mem_ctx, "%s%s", GROUP_PREFIX, sidstr);
}
Example #3
0
void netsamlogon_clear_cached_user(const struct dom_sid *user_sid)
{
    char keystr[DOM_SID_STR_BUFLEN];

    if (!netsamlogon_cache_init()) {
        DEBUG(0,("netsamlogon_clear_cached_user: cannot open "
                 "%s for write!\n",
                 NETSAMLOGON_TDB));
        return;
    }

    /* Prepare key as DOMAIN-SID/USER-RID string */
    dom_sid_string_buf(user_sid, keystr, sizeof(keystr));

    DEBUG(10,("netsamlogon_clear_cached_user: SID [%s]\n", keystr));

    tdb_delete_bystring(netsamlogon_tdb, keystr);
}
Example #4
0
char *sid_to_fstring(fstring sidstr_out, const struct dom_sid *sid)
{
	dom_sid_string_buf(sid, sidstr_out, sizeof(fstring));
	return sidstr_out;
}
Example #5
0
bool netsamlogon_cache_store(const char *username, struct netr_SamInfo3 *info3)
{
    uint8_t dummy = 0;
    TDB_DATA data = { .dptr = &dummy, .dsize = sizeof(dummy) };
    char keystr[DOM_SID_STR_BUFLEN];
    bool result = false;
    struct dom_sid	user_sid;
    TALLOC_CTX *tmp_ctx = talloc_stackframe();
    DATA_BLOB blob;
    enum ndr_err_code ndr_err;
    struct netsamlogoncache_entry r;
    int ret;

    if (!info3) {
        return false;
    }

    if (!netsamlogon_cache_init()) {
        DEBUG(0,("netsamlogon_cache_store: cannot open %s for write!\n",
                 NETSAMLOGON_TDB));
        return false;
    }

    /*
     * First write a record with just the domain sid for
     * netsamlogon_cache_domain_known. Use TDB_INSERT to avoid
     * overwriting potentially other data. We're just interested
     * in the existence of that record.
     */
    dom_sid_string_buf(info3->base.domain_sid, keystr, sizeof(keystr));

    ret = tdb_store_bystring(netsamlogon_tdb, keystr, data, TDB_INSERT);

    if ((ret == -1) && (tdb_error(netsamlogon_tdb) != TDB_ERR_EXISTS)) {
        DBG_WARNING("Could not store domain marker for %s: %s\n",
                    keystr, tdb_errorstr(netsamlogon_tdb));
        TALLOC_FREE(tmp_ctx);
        return false;
    }

    sid_compose(&user_sid, info3->base.domain_sid, info3->base.rid);

    /* Prepare key as DOMAIN-SID/USER-RID string */
    dom_sid_string_buf(&user_sid, keystr, sizeof(keystr));

    DEBUG(10,("netsamlogon_cache_store: SID [%s]\n", keystr));

    /* Prepare data */

    if (info3->base.full_name.string == NULL) {
        struct netr_SamInfo3 *cached_info3;
        const char *full_name = NULL;

        cached_info3 = netsamlogon_cache_get(tmp_ctx, &user_sid);
        if (cached_info3 != NULL) {
            full_name = cached_info3->base.full_name.string;
        }

        if (full_name != NULL) {
            info3->base.full_name.string = talloc_strdup(info3, full_name);
        }
    }

    /* only Samba fills in the username, not sure why NT doesn't */
    /* so we fill it in since winbindd_getpwnam() makes use of it */

    if (!info3->base.account_name.string) {
        info3->base.account_name.string = talloc_strdup(info3, username);
    }

    r.timestamp = time(NULL);
    r.info3 = *info3;

    if (DEBUGLEVEL >= 10) {
        NDR_PRINT_DEBUG(netsamlogoncache_entry, &r);
    }

    ndr_err = ndr_push_struct_blob(&blob, tmp_ctx, &r,
                                   (ndr_push_flags_fn_t)ndr_push_netsamlogoncache_entry);
    if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
        DEBUG(0,("netsamlogon_cache_store: failed to push entry to cache\n"));
        TALLOC_FREE(tmp_ctx);
        return false;
    }

    data.dsize = blob.length;
    data.dptr = blob.data;

    if (tdb_store_bystring(netsamlogon_tdb, keystr, data, TDB_REPLACE) == 0) {
        result = true;
    }

    TALLOC_FREE(tmp_ctx);

    return result;
}

/***********************************************************************
 Retrieves a netr_SamInfo3 structure from a tdb.  Caller must
 free the user_info struct (talloced memory)
***********************************************************************/

struct netr_SamInfo3 *netsamlogon_cache_get(TALLOC_CTX *mem_ctx, const struct dom_sid *user_sid)
{
    struct netr_SamInfo3 *info3 = NULL;
    TDB_DATA data;
    char keystr[DOM_SID_STR_BUFLEN];
    enum ndr_err_code ndr_err;
    DATA_BLOB blob;
    struct netsamlogoncache_entry r;

    if (!netsamlogon_cache_init()) {
        DEBUG(0,("netsamlogon_cache_get: cannot open %s for write!\n",
                 NETSAMLOGON_TDB));
        return NULL;
    }

    /* Prepare key as DOMAIN-SID/USER-RID string */
    dom_sid_string_buf(user_sid, keystr, sizeof(keystr));
    DEBUG(10,("netsamlogon_cache_get: SID [%s]\n", keystr));
    data = tdb_fetch_bystring( netsamlogon_tdb, keystr );

    if (!data.dptr) {
        return NULL;
    }

    info3 = talloc_zero(mem_ctx, struct netr_SamInfo3);
    if (!info3) {
        goto done;
    }

    blob = data_blob_const(data.dptr, data.dsize);

    ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &r,
                                   (ndr_pull_flags_fn_t)ndr_pull_netsamlogoncache_entry);

    if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
        DEBUG(0,("netsamlogon_cache_get: failed to pull entry from cache\n"));
        tdb_delete_bystring(netsamlogon_tdb, keystr);
        TALLOC_FREE(info3);
        goto done;
    }

    if (DEBUGLEVEL >= 10) {
        NDR_PRINT_DEBUG(netsamlogoncache_entry, &r);
    }

    info3 = (struct netr_SamInfo3 *)talloc_memdup(mem_ctx, &r.info3,
            sizeof(r.info3));

done:
    SAFE_FREE(data.dptr);

    return info3;
}

bool netsamlogon_cache_have(const struct dom_sid *sid)
{
    char keystr[DOM_SID_STR_BUFLEN];
    bool ok;

    if (!netsamlogon_cache_init()) {
        DBG_WARNING("Cannot open %s\n", NETSAMLOGON_TDB);
        return false;
    }

    dom_sid_string_buf(sid, keystr, sizeof(keystr));

    ok = tdb_exists(netsamlogon_tdb, string_term_tdb_data(keystr));
    return ok;
}
Example #6
0
/*
  reply to a ADS style GETDC request
 */
static NTSTATUS nbtd_netlogon_samlogon(
	struct nbtd_server *nbtsrv,
	struct nbt_name *dst_name,
	const struct socket_address *src,
	struct nbt_netlogon_packet *netlogon,
	TALLOC_CTX *mem_ctx,
	struct nbt_netlogon_response **presponse,
	char **preply_mailslot)
{
	struct ldb_context *samctx;
	struct dom_sid *sid = NULL;
	struct nbt_netlogon_response *response = NULL;
	char *reply_mailslot = NULL;
	NTSTATUS status;

	/* only answer getdc requests on the PDC or LOGON names */
	if ((dst_name->type != NBT_NAME_PDC) &&
	    (dst_name->type != NBT_NAME_LOGON)) {
		return NT_STATUS_NOT_SUPPORTED;
	}

	samctx = nbtsrv->sam_ctx;

	if (netlogon->req.logon.sid_size != 0) {
		sid = &netlogon->req.logon.sid;
	}

	reply_mailslot = talloc_strdup(
		mem_ctx, netlogon->req.logon.mailslot_name);
	if (reply_mailslot == NULL) {
		return NT_STATUS_NO_MEMORY;
	}

	response = talloc_zero(mem_ctx, struct nbt_netlogon_response);
	if (response == NULL) {
		TALLOC_FREE(reply_mailslot);
		return NT_STATUS_NO_MEMORY;
	}
	response->response_type = NETLOGON_SAMLOGON;

	status = fill_netlogon_samlogon_response(
		samctx, response, NULL, dst_name->name, sid, NULL,
		netlogon->req.logon.user_name,
		netlogon->req.logon.acct_control, src->addr,
		netlogon->req.logon.nt_version, nbtsrv->task->lp_ctx,
		&response->data.samlogon, false);
	if (!NT_STATUS_IS_OK(status)) {
		char buf[DOM_SID_STR_BUFLEN];
		dom_sid_string_buf(sid, buf, sizeof(buf));

		DBG_NOTICE("NBT netlogon query failed domain=%s sid=%s "
			   "version=%d - %s\n", dst_name->name, buf,
			   netlogon->req.logon.nt_version, nt_errstr(status));
		TALLOC_FREE(reply_mailslot);
		TALLOC_FREE(response);
		return status;
	}

	*presponse = response;
	*preply_mailslot = reply_mailslot;
	return NT_STATUS_OK;
}