Example #1
0
static struct torture_tcase *add_test(struct torture_suite *suite, uint32_t bindoptions, 
				     bool keyexchange, bool ntlm2, bool lm_key)
{
	char *name = NULL;
	struct secret_settings *settings;

	settings = talloc_zero(suite, struct secret_settings);
	settings->bindoptions = bindoptions;

	if (bindoptions == DCERPC_PUSH_BIGENDIAN)
		name = talloc_strdup(suite, "bigendian");
	else if (bindoptions == DCERPC_SEAL)
		name = talloc_strdup(suite, "seal");
	else if (bindoptions == 0) 
		name = talloc_strdup(suite, "none");
	else
		name = talloc_strdup(suite, "unknown");

	name = talloc_asprintf_append_buffer(name, " keyexchange:%s", keyexchange?"yes":"no");
	settings->keyexchange = keyexchange;

	name = talloc_asprintf_append_buffer(name, " ntlm2:%s", ntlm2?"yes":"no");
	settings->ntlm2 = ntlm2;

	name = talloc_asprintf_append_buffer(name, " lm_key:%s", lm_key?"yes":"no");
	settings->lm_key = lm_key;

	return torture_suite_add_simple_tcase_const(suite, name, test_secrets,
			settings);
}
Example #2
0
static NTSTATUS gpo_prepare_local_store(TALLOC_CTX *mem_ctx,
					const char *unix_path)
{
	const char *top_dir = lock_path(GPO_CACHE_DIR);
	char *current_dir;
	char *tok;

	current_dir = talloc_strdup(mem_ctx, top_dir);
	NT_STATUS_HAVE_NO_MEMORY(current_dir);

	if ((mkdir(top_dir, 0644)) < 0 && errno != EEXIST) {
		return NT_STATUS_ACCESS_DENIED;
	}

	while (next_token_talloc(mem_ctx, &unix_path, &tok, "/")) {
		if (strequal(tok, GPO_CACHE_DIR)) {
			break;
		}
	}

	while (next_token_talloc(mem_ctx, &unix_path, &tok, "/")) {
		current_dir = talloc_asprintf_append_buffer(current_dir, "/%s", tok);
		NT_STATUS_HAVE_NO_MEMORY(current_dir);

		if ((mkdir(current_dir, 0644)) < 0 && errno != EEXIST) {
			return NT_STATUS_ACCESS_DENIED;
		}
	}

	return NT_STATUS_OK;
}
Example #3
0
static char *def_tuple(CTX *ctx, struct ir_struct_type *st, bool add_names)
{
    // NOTE: we use the same C type for empty tuples and compounds; should be ok
    if (st->members_count == 0)
        return VOID_MANGLE;
    char *m = get_mangle(ctx, st);
    if (m)
        return m;
    assert(ctx->writing_types);
    m = talloc_strdup(ctx, MANGLE_PREFIX "tuple_");
    for (int n = 0; n < st->members_count; n++) {
        struct ir_struct_member *sm = st->members[n];
        mangle_append_sub(&m, def_type(ctx, sm->type));
        assert(add_names == (sm->name[0]));
        if (sm->name)
            m = talloc_asprintf_append_buffer(m, "n%zd_%s_", strlen(sm->name),
                                              sm->name);
    }
    if (use_anon_mangle_for_tuples) {
        char *new_mangle = HT_GET_DEF(dstr, dstr, ctx->tuple_abbrev, m, NULL);
        if (!new_mangle) {
            new_mangle = gen_anon_mangle(ctx, "tuple");
            HT_INSERT(dstr, dstr, ctx->tuple_abbrev, m, new_mangle);
        }
        m = new_mangle;
    }
    add_mangle(ctx, st, m);
    if (!check_redef(ctx, m))
        write_struct(ctx, st, m);
    return m;
}
Example #4
0
/*
  encode an ACL in SDDL format
*/
static char *sddl_encode_acl(TALLOC_CTX *mem_ctx, const struct security_acl *acl,
			     uint32_t flags, const struct dom_sid *domain_sid)
{
	char *sddl;
	uint32_t i;

	/* add any ACL flags */
	sddl = sddl_flags_to_string(mem_ctx, acl_flags, flags, false);
	if (sddl == NULL) goto failed;

	/* now the ACEs, encoded in braces */
	for (i=0;i<acl->num_aces;i++) {
		char *ace = sddl_encode_ace(sddl, &acl->aces[i], domain_sid);
		if (ace == NULL) goto failed;
		sddl = talloc_asprintf_append_buffer(sddl, "(%s)", ace);
		if (sddl == NULL) goto failed;
		talloc_free(ace);
	}

	return sddl;

failed:
	talloc_free(sddl);
	return NULL;
}
Example #5
0
/*
  turn a set of flags into a string
*/
static char *sddl_flags_to_string(TALLOC_CTX *mem_ctx, const struct flag_map *map,
				  uint32_t flags, bool check_all)
{
	int i;
	char *s;

	/* try to find an exact match */
	for (i=0;map[i].name;i++) {
		if (map[i].flag == flags) {
			return talloc_strdup(mem_ctx, map[i].name);
		}
	}

	s = talloc_strdup(mem_ctx, "");

	/* now by bits */
	for (i=0;map[i].name;i++) {
		if ((flags & map[i].flag) != 0) {
			s = talloc_asprintf_append_buffer(s, "%s", map[i].name);
			if (s == NULL) goto failed;
			flags &= ~map[i].flag;
		}
	}

	if (check_all && flags != 0) {
		goto failed;
	}

	return s;

failed:
	talloc_free(s);
	return NULL;
}
Example #6
0
/* Return two stable query strings that identify exactly the matched
 * and unmatched messages currently in thread.  If there are no
 * matched or unmatched messages, the returned buffers will be
 * NULL. */
static int
get_thread_query (notmuch_thread_t *thread,
		  char **matched_out, char **unmatched_out)
{
    notmuch_messages_t *messages;
    char *escaped = NULL;
    size_t escaped_len = 0;

    *matched_out = *unmatched_out = NULL;

    for (messages = notmuch_thread_get_messages (thread);
	 notmuch_messages_valid (messages);
	 notmuch_messages_move_to_next (messages))
    {
	notmuch_message_t *message = notmuch_messages_get (messages);
	const char *mid = notmuch_message_get_message_id (message);
	/* Determine which query buffer to extend */
	char **buf = notmuch_message_get_flag (
	    message, NOTMUCH_MESSAGE_FLAG_MATCH) ? matched_out : unmatched_out;
	/* Add this message's id: query.  Since "id" is an exclusive
	 * prefix, it is implicitly 'or'd together, so we only need to
	 * join queries with a space. */
	if (make_boolean_term (thread, "id", mid, &escaped, &escaped_len) < 0)
	    return -1;
	if (*buf)
	    *buf = talloc_asprintf_append_buffer (*buf, " %s", escaped);
	else
	    *buf = talloc_strdup (thread, escaped);
	if (!*buf)
	    return -1;
    }
    talloc_free (escaped);
    return 0;
}
Example #7
0
int domain_to_basedn(TALLOC_CTX *memctx, const char *domain, char **basedn)
{
    const char *s;
    char *dn;
    char *p;
    int l;

    if (!domain || !basedn) {
        return EINVAL;
    }

    s = domain;
    dn = talloc_strdup(memctx, "dc=");

    while ((p = strchr(s, '.'))) {
        l = p - s;
        dn = talloc_asprintf_append_buffer(dn, "%.*s,dc=", l, s);
        if (!dn) {
            return ENOMEM;
        }
        s = p + 1;
    }
    dn = talloc_strdup_append_buffer(dn, s);
    if (!dn) {
        return ENOMEM;
    }

    for (p=dn; *p; ++p) {
        *p = tolower(*p);
    }

    *basedn = dn;
    return EOK;
}
Example #8
0
void winbindd_list_trusted_domains(struct winbindd_cli_state *state)
{
	struct winbindd_tdc_domain *dom_list = NULL;
	struct winbindd_tdc_domain *d = NULL;
	size_t num_domains = 0;
	int extra_data_len = 0;
	char *extra_data = NULL;
	int i = 0;

	DEBUG(3, ("[%5lu]: list trusted domains\n",
		  (unsigned long)state->pid));

	if( !wcache_tdc_fetch_list( &dom_list, &num_domains )) {
		request_error(state);	
		goto done;
	}

	extra_data = talloc_strdup(state->mem_ctx, "");
	if (extra_data == NULL) {
		request_error(state);
		goto done;
	}

	for ( i = 0; i < num_domains; i++ ) {
		struct winbindd_domain *domain;
		bool is_online = true;		

		d = &dom_list[i];
		domain = find_domain_from_name_noinit(d->domain_name);
		if (domain) {
			is_online = domain->online;
		}
		extra_data = talloc_asprintf_append_buffer(
			extra_data,
			"%s\\%s\\%s\\%s\\%s\\%s\\%s\\%s\n",
			d->domain_name,
			d->dns_name ? d->dns_name : d->domain_name,
			sid_string_talloc(state->mem_ctx, &d->sid),
			get_trust_type_string(d),
			trust_is_transitive(d) ? "Yes" : "No",
			trust_is_inbound(d) ? "Yes" : "No",
			trust_is_outbound(d) ? "Yes" : "No",
			is_online ? "Online" : "Offline" );
	}

	extra_data_len = strlen(extra_data);
	if (extra_data_len > 0) {

		/* Strip the last \n */
		extra_data[extra_data_len-1] = '\0';

		state->response->extra_data.data = extra_data;
		state->response->length += extra_data_len;
	}

	request_ok(state);	
done:
	TALLOC_FREE( dom_list );
}
Example #9
0
_PUBLIC_ void ndr_print_string_helper(struct ndr_print *ndr, const char *format, ...)
{
	va_list ap;
	int i;

	for (i=0;i<ndr->depth;i++) {
		ndr->private_data = talloc_asprintf_append_buffer(
					(char *)ndr->private_data, "    ");
	}

	va_start(ap, format);
	ndr->private_data = talloc_vasprintf_append_buffer((char *)ndr->private_data, 
						    format, ap);
	va_end(ap);
	ndr->private_data = talloc_asprintf_append_buffer((char *)ndr->private_data, 
						   "\n");
}
Example #10
0
static void mangle_append_sub(char **s, char *m)
{
    void *p = talloc_parent(*s);
    assert(p);
    // Kill prefix, for not making type names not ridiculous long.
    if (strncmp(m, MANGLE_PREFIX, strlen(MANGLE_PREFIX)) == 0)
        m = m + strlen(MANGLE_PREFIX);
    *s = talloc_asprintf_append_buffer(*s, "%zd_%s_", strlen(m), m);
}
Example #11
0
void wins_hook(struct winsdb_handle *h, const struct winsdb_record *rec, 
	       enum wins_hook_action action, const char *wins_hook_script)
{
	uint32_t i, length;
	int child;
	char *cmd = NULL;
	TALLOC_CTX *tmp_mem = NULL;

	if (!wins_hook_script || !wins_hook_script[0]) return;

	tmp_mem = talloc_new(h);
	if (!tmp_mem) goto failed;

	length = winsdb_addr_list_length(rec->addresses);

	if (action == WINS_HOOK_MODIFY && length < 1) {
		action = WINS_HOOK_DELETE;
	}

	cmd = talloc_asprintf(tmp_mem,
			      "%s %s %s %02x %ld",
			      wins_hook_script,
			      wins_hook_action_string(action),
			      rec->name->name,
			      rec->name->type,
			      (long int) rec->expire_time);
	if (!cmd) goto failed;

	for (i=0; rec->addresses[i]; i++) {
		cmd = talloc_asprintf_append_buffer(cmd, " %s", rec->addresses[i]->address);
		if (!cmd) goto failed;
	}

	DEBUG(10,("call wins hook '%s'\n", cmd));

	/* signal handling in posix really sucks - doing this in a library
	   affects the whole app, but what else to do?? */
	signal(SIGCHLD, SIG_IGN);

	child = fork();
	if (child == (pid_t)-1) {
		goto failed;
	}

	if (child == 0) {
/* TODO: close file handles */
		execl("/bin/sh", "sh", "-c", cmd, NULL);
		_exit(0);
	}

	talloc_free(tmp_mem);
	return;
failed:
	talloc_free(tmp_mem);
	DEBUG(0,("FAILED: calling wins hook '%s'\n", wins_hook_script));
}
Example #12
0
void websrv_output_headers(struct websrv_context *web, const char *status, struct http_header *headers)
{
	char *s;
	DATA_BLOB b;
	struct http_header *hdr;

	s = talloc_asprintf(web, "HTTP/1.0 %s\r\n", status);
	if (s == NULL) return;
	for (hdr = headers; hdr; hdr = hdr->next) {
		s = talloc_asprintf_append_buffer(s, "%s: %s\r\n", hdr->name, hdr->value);
	}

	s = talloc_asprintf_append_buffer(s, "\r\n");

	b = web->output.content;
	web->output.content = data_blob_string_const(s);
	websrv_output(web, b.data, b.length);
	data_blob_free(&b);
}
Example #13
0
/*
  form a binding string from a binding structure
*/
_PUBLIC_ char *dcerpc_binding_string(TALLOC_CTX *mem_ctx, const struct dcerpc_binding *b)
{
	char *s = talloc_strdup(mem_ctx, "");
	int i;
	const char *t_name = NULL;

	if (b->transport != NCA_UNKNOWN) {
		t_name = derpc_transport_string_by_transport(b->transport);
		if (!t_name) {
			return NULL;
		}
	}

	if (!GUID_all_zero(&b->object.uuid)) { 
		s = talloc_asprintf(s, "%s@",
				    GUID_string(mem_ctx, &b->object.uuid));
	}

	if (t_name != NULL) {
		s = talloc_asprintf_append_buffer(s, "%s:", t_name);
		if (s == NULL) {
			return NULL;
		}
	}

	if (b->host) {
		s = talloc_asprintf_append_buffer(s, "%s", b->host);
	}

	if (!b->endpoint && !b->options && !b->flags) {
		return s;
	}

	s = talloc_asprintf_append_buffer(s, "[");

	if (b->endpoint) {
		s = talloc_asprintf_append_buffer(s, "%s", b->endpoint);
	}

	/* this is a *really* inefficent way of dealing with strings,
	   but this is rarely called and the strings are always short,
	   so I don't care */
	for (i=0;b->options && b->options[i];i++) {
		s = talloc_asprintf_append_buffer(s, ",%s", b->options[i]);
		if (!s) return NULL;
	}

	for (i=0;i<ARRAY_SIZE(ncacn_options);i++) {
		if (b->flags & ncacn_options[i].flag) {
			s = talloc_asprintf_append_buffer(s, ",%s", ncacn_options[i].name);
			if (!s) return NULL;
		}
	}

	s = talloc_asprintf_append_buffer(s, "]");

	return s;
}
Example #14
0
/*
  turn a node status flags field into a string
*/
static char *node_status_flags(TALLOC_CTX *mem_ctx, uint16_t flags)
{
	char *ret;
	const char *group = "       ";
	const char *type = "B";

	if (flags & NBT_NM_GROUP) {
		group = "<GROUP>";
	}

	switch (flags & NBT_NM_OWNER_TYPE) {
	case NBT_NODE_B: 
		type = "B";
		break;
	case NBT_NODE_P: 
		type = "P";
		break;
	case NBT_NODE_M: 
		type = "M";
		break;
	case NBT_NODE_H: 
		type = "H";
		break;
	}

	ret = talloc_asprintf(mem_ctx, "%s %s", group, type);

	if (flags & NBT_NM_DEREGISTER) {
		ret = talloc_asprintf_append_buffer(ret, " <DEREGISTERING>");
	}
	if (flags & NBT_NM_CONFLICT) {
		ret = talloc_asprintf_append_buffer(ret, " <CONFLICT>");
	}
	if (flags & NBT_NM_ACTIVE) {
		ret = talloc_asprintf_append_buffer(ret, " <ACTIVE>");
	}
	if (flags & NBT_NM_PERMANENT) {
		ret = talloc_asprintf_append_buffer(ret, " <PERMANENT>");
	}
	
	return ret;
}
Example #15
0
/*
  encode a security descriptor to SDDL format
*/
char *sddl_encode(TALLOC_CTX *mem_ctx, const struct security_descriptor *sd,
		  const struct dom_sid *domain_sid)
{
	char *sddl;
	TALLOC_CTX *tmp_ctx;

	/* start with a blank string */
	sddl = talloc_strdup(mem_ctx, "");
	if (sddl == NULL) goto failed;

	tmp_ctx = talloc_new(mem_ctx);

	if (sd->owner_sid != NULL) {
		char *sid = sddl_encode_sid(tmp_ctx, sd->owner_sid, domain_sid);
		if (sid == NULL) goto failed;
		sddl = talloc_asprintf_append_buffer(sddl, "O:%s", sid);
		if (sddl == NULL) goto failed;
	}

	if (sd->group_sid != NULL) {
		char *sid = sddl_encode_sid(tmp_ctx, sd->group_sid, domain_sid);
		if (sid == NULL) goto failed;
		sddl = talloc_asprintf_append_buffer(sddl, "G:%s", sid);
		if (sddl == NULL) goto failed;
	}

	if ((sd->type & SEC_DESC_DACL_PRESENT) && sd->dacl != NULL) {
		char *acl = sddl_encode_acl(tmp_ctx, sd->dacl, sd->type, domain_sid);
		if (acl == NULL) goto failed;
		sddl = talloc_asprintf_append_buffer(sddl, "D:%s", acl);
		if (sddl == NULL) goto failed;
	}

	if ((sd->type & SEC_DESC_SACL_PRESENT) && sd->sacl != NULL) {
		char *acl = sddl_encode_acl(tmp_ctx, sd->sacl, sd->type>>1, domain_sid);
		if (acl == NULL) goto failed;
		sddl = talloc_asprintf_append_buffer(sddl, "S:%s", acl);
		if (sddl == NULL) goto failed;
	}
Example #16
0
/** join a list back to one (shell-like) string; entries 
 * separated by spaces, using quotes where necessary */
_PUBLIC_ char *str_list_join_shell(TALLOC_CTX *mem_ctx, const char **list, char sep)
{
	char *ret = NULL;
	int i;
	
	if (list[0] == NULL)
		return talloc_strdup(mem_ctx, "");

	if (strchr(list[0], ' ') || strlen(list[0]) == 0) 
		ret = talloc_asprintf(mem_ctx, "\"%s\"", list[0]);
	else 
		ret = talloc_strdup(mem_ctx, list[0]);

	for (i = 1; list[i]; i++) {
		if (strchr(list[i], ' ') || strlen(list[i]) == 0) 
			ret = talloc_asprintf_append_buffer(ret, "%c\"%s\"", sep, list[i]);
		else 
			ret = talloc_asprintf_append_buffer(ret, "%c%s", sep, list[i]);
	}

	return ret;
}
Example #17
0
static char *
_optimize_tag_query (void *ctx, const char *orig_query_string,
		     const tag_op_list_t *list)
{
    /* This is subtler than it looks.  Xapian ignores the '-' operator
     * at the beginning both queries and parenthesized groups and,
     * furthermore, the presence of a '-' operator at the beginning of
     * a group can inhibit parsing of the previous operator.  Hence,
     * the user-provided query MUST appear first, but it is safe to
     * parenthesize and the exclusion part of the query must not use
     * the '-' operator (though the NOT operator is fine). */

    char *escaped = NULL;
    size_t escaped_len = 0;
    char *query_string;
    const char *join = "";
    size_t i;

    /* Don't optimize if there are no tag changes. */
    if (tag_op_list_size (list) == 0)
	return talloc_strdup (ctx, orig_query_string);

    /* Build the new query string */
    if (strcmp (orig_query_string, "*") == 0)
	query_string = talloc_strdup (ctx, "(");
    else
	query_string = talloc_asprintf (ctx, "( %s ) and (", orig_query_string);

    for (i = 0; i < tag_op_list_size (list) && query_string; i++) {
	/* XXX in case of OOM, query_string will be deallocated when
	 * ctx is, which might be at shutdown */
	if (make_boolean_term (ctx,
			       "tag", tag_op_list_tag (list, i),
			       &escaped, &escaped_len))
	    return NULL;

	query_string = talloc_asprintf_append_buffer (
	    query_string, "%s%s%s", join,
	    tag_op_list_isremove (list, i) ? "" : "not ",
	    escaped);
	join = " or ";
    }

    if (query_string)
	query_string = talloc_strdup_append_buffer (query_string, ")");

    talloc_free (escaped);
    return query_string;
}
Example #18
0
/**
 * join a list back to one string 
 */
_PUBLIC_ char *str_list_join(TALLOC_CTX *mem_ctx, const char **list, char separator)
{
	char *ret = NULL;
	int i;
	
	if (list[0] == NULL)
		return talloc_strdup(mem_ctx, "");

	ret = talloc_strdup(mem_ctx, list[0]);

	for (i = 1; list[i]; i++) {
		ret = talloc_asprintf_append_buffer(ret, "%c%s", separator, list[i]);
	}

	return ret;
}
Example #19
0
static void usersids_recv_sids(struct composite_context *ctx)
{
	struct wbsrv_samba3_call *s3call =
		talloc_get_type(ctx->async.private_data,
				struct wbsrv_samba3_call);
	int i, num_sids;
	struct dom_sid **sids;
	char *sids_string;
	NTSTATUS status;

	status = wb_cmd_usersids_recv(ctx, s3call, &num_sids, &sids);
	if (!NT_STATUS_IS_OK(status)) goto done;

	sids_string = talloc_strdup(s3call, "");
	if (sids_string == NULL) {
		status = NT_STATUS_NO_MEMORY;
		goto done;
	}

	for (i=0; i<num_sids; i++) {
		sids_string = talloc_asprintf_append_buffer(
			sids_string, "%s\n", dom_sid_string(s3call, sids[i]));
		if (sids_string == NULL) {
			status = NT_STATUS_NO_MEMORY;
			goto done;
		}
	}

	s3call->response.result = WINBINDD_OK;
	s3call->response.extra_data.data = sids_string;
	s3call->response.length += strlen(sids_string);
	s3call->response.data.num_entries = num_sids;

	/* Hmmmm. Nasty protocol -- who invented the zeros between the
	 * SIDs? Hmmm. Could have been me -- vl */

	while (*sids_string != '\0') {
		if ((*sids_string) == '\n') {
			*sids_string = '\0';
		}
		sids_string += 1;
	}

 done:
	wbsrv_samba3_async_epilogue(status, s3call);
}
Example #20
0
static char *def_array_type(CTX *ctx, struct ir_array_type *at)
{
    char *m = get_mangle(ctx, at);
    if (m)
        return m;
    assert(ctx->writing_types);
    m = talloc_strdup(ctx, MANGLE_PREFIX "arr_");
    m = talloc_asprintf_append_buffer(m, "%d_", at->dimension);
    mangle_append_sub(&m, def_type(ctx, at->item_type));
    add_mangle(ctx, at, m);
    if (!check_redef(ctx, m)) {
        wf(ctx, "typedef struct %s {", m);
        indent_in(ctx);
        wf(ctx, "%s a[%d];", def_type(ctx, at->item_type), at->dimension);
        indent_out(ctx);
        wf(ctx, "} %s;", m);
    }
    return m;
}
Example #21
0
static void list_trustdom_recv_doms(struct composite_context *ctx)
{
	struct wbsrv_samba3_call *s3call =
		talloc_get_type(ctx->async.private_data,
				struct wbsrv_samba3_call);
	int i, num_domains;
	struct wb_dom_info **domains;
	NTSTATUS status;
	char *result;

	status = wb_cmd_list_trustdoms_recv(ctx, s3call, &num_domains,
					    &domains);
	if (!NT_STATUS_IS_OK(status)) goto done;

	result = talloc_strdup(s3call, "");
	if (result == NULL) {
		status = NT_STATUS_NO_MEMORY;
		goto done;
	}

	for (i=0; i<num_domains; i++) {
		result = talloc_asprintf_append_buffer(
			result, "%s\\%s\\%s",
			domains[i]->name, domains[i]->name,
			dom_sid_string(s3call, domains[i]->sid));
	}

	if (result == NULL) {
		status = NT_STATUS_NO_MEMORY;
		goto done;
	}

	s3call->response.result = WINBINDD_OK;
	if (num_domains > 0) {
		s3call->response.extra_data.data = result;
		s3call->response.length += strlen(result)+1;
	}

 done:
	wbsrv_samba3_async_epilogue(status, s3call);
}
Example #22
0
File: misc.c Project: Deadsign/mpv
void merge_playlist_files(struct playlist *pl)
{
    if (!pl->first)
        return;
    char *edl = talloc_strdup(NULL, "edl://");
    for (struct playlist_entry *e = pl->first; e; e = e->next) {
        if (e != pl->first)
            edl = talloc_strdup_append_buffer(edl, ";");
        // Escape if needed
        if (e->filename[strcspn(e->filename, "=%,;\n")] ||
            bstr_strip(bstr0(e->filename)).len != strlen(e->filename))
        {
            // %length%
            edl = talloc_asprintf_append_buffer(edl, "%%%zd%%", strlen(e->filename));
        }
        edl = talloc_strdup_append_buffer(edl, e->filename);
    }
    playlist_clear(pl);
    playlist_add_file(pl, edl);
    talloc_free(edl);
}
Example #23
0
struct composite_context *libnet_UnbecomeDC_send(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, struct libnet_UnbecomeDC *r)
{
	struct composite_context *c;
	struct libnet_UnbecomeDC_state *s;
	char *tmp_name;

	c = composite_create(mem_ctx, ctx->event_ctx);
	if (c == NULL) return NULL;

	s = talloc_zero(c, struct libnet_UnbecomeDC_state);
	if (composite_nomem(s, c)) return c;
	c->private_data = s;
	s->creq		= c;
	s->libnet	= ctx;

	/* Domain input */
	s->domain.dns_name	= talloc_strdup(s, r->in.domain_dns_name);
	if (composite_nomem(s->domain.dns_name, c)) return c;
	s->domain.netbios_name	= talloc_strdup(s, r->in.domain_netbios_name);
	if (composite_nomem(s->domain.netbios_name, c)) return c;

	/* Source DSA input */
	s->source_dsa.address	= talloc_strdup(s, r->in.source_dsa_address);
	if (composite_nomem(s->source_dsa.address, c)) return c;

	/* Destination DSA input */
	s->dest_dsa.netbios_name= talloc_strdup(s, r->in.dest_dsa_netbios_name);
	if (composite_nomem(s->dest_dsa.netbios_name, c)) return c;

	/* Destination DSA dns_name construction */
	tmp_name		= strlower_talloc(s, s->dest_dsa.netbios_name);
	if (composite_nomem(tmp_name, c)) return c;
	s->dest_dsa.dns_name	= talloc_asprintf_append_buffer(tmp_name, ".%s",
				  			 s->domain.dns_name);
	if (composite_nomem(s->dest_dsa.dns_name, c)) return c;

	unbecomeDC_send_cldap(s);
	return c;
}
Example #24
0
static void userdomgroups_recv_groups(struct composite_context *ctx)
{
	struct wbsrv_samba3_call *s3call =
		talloc_get_type(ctx->async.private_data,
				struct wbsrv_samba3_call);
	int i, num_sids;
	struct dom_sid **sids;
	char *sids_string;
	NTSTATUS status;

	status = wb_cmd_userdomgroups_recv(ctx, s3call, &num_sids, &sids);
	if (!NT_STATUS_IS_OK(status)) goto done;

	sids_string = talloc_strdup(s3call, "");
	if (sids_string == NULL) {
		status = NT_STATUS_NO_MEMORY;
		goto done;
	}

	for (i=0; i<num_sids; i++) {
		sids_string = talloc_asprintf_append_buffer(
			sids_string, "%s\n", dom_sid_string(s3call, sids[i]));
	}

	if (sids_string == NULL) {
		status = NT_STATUS_NO_MEMORY;
		goto done;
	}

	s3call->response.result = WINBINDD_OK;
	s3call->response.extra_data.data = sids_string;
	s3call->response.length += strlen(sids_string)+1;
	s3call->response.data.num_entries = num_sids;

 done:
	wbsrv_samba3_async_epilogue(status, s3call);
}
Example #25
0
enum winbindd_result winbindd_dual_list_trusted_domains(struct winbindd_domain *domain,
							struct winbindd_cli_state *state)
{
	int i;
	int extra_data_len = 0;
	char *extra_data;
	NTSTATUS result;
	bool have_own_domain = False;
	struct netr_DomainTrustList trusts;

	DEBUG(3, ("[%5lu]: list trusted domains\n",
		  (unsigned long)state->pid));

	result = domain->methods->trusted_domains(domain, state->mem_ctx,
						  &trusts);

	if (!NT_STATUS_IS_OK(result)) {
		DEBUG(3, ("winbindd_dual_list_trusted_domains: trusted_domains returned %s\n",
			nt_errstr(result) ));
		return WINBINDD_ERROR;
	}

	extra_data = talloc_strdup(state->mem_ctx, "");

	for (i=0; i<trusts.count; i++) {

		if (trusts.array[i].sid == NULL) {
			continue;
		}
		if (dom_sid_equal(trusts.array[i].sid, &global_sid_NULL)) {
			continue;
		}

		extra_data = talloc_asprintf_append_buffer(
		    extra_data, "%s\\%s\\%s\\%u\\%u\\%u\n",
		    trusts.array[i].netbios_name, trusts.array[i].dns_name,
		    sid_string_talloc(state->mem_ctx, trusts.array[i].sid),
		    trusts.array[i].trust_flags,
		    (uint32_t)trusts.array[i].trust_type,
		    trusts.array[i].trust_attributes);
	}

	/* add our primary domain */

	for (i=0; i<trusts.count; i++) {
		if (strequal(trusts.array[i].netbios_name, domain->name)) {
			have_own_domain = True;
			break;
		}
	}

	if (state->request->data.list_all_domains && !have_own_domain) {
		extra_data = talloc_asprintf_append_buffer(
			extra_data, "%s\\%s\\%s\n", domain->name,
			domain->alt_name != NULL ?
				domain->alt_name :
				domain->name,
			sid_string_talloc(state->mem_ctx, &domain->sid));
	}

	extra_data_len = strlen(extra_data);
	if (extra_data_len > 0) {

		/* Strip the last \n */
		extra_data[extra_data_len-1] = '\0';

		state->response->extra_data.data = extra_data;
		state->response->length += extra_data_len;
	}

	return WINBINDD_OK;
}
Example #26
0
/*
  miscellaneous tests to try to get a higher test coverage percentage
*/
static bool test_misc(void)
{
	void *root, *p1;
	char *p2;
	double *d;
	const char *name;

	printf("test: misc\n# MISCELLANEOUS\n");

	root = talloc_new(NULL);

	p1 = talloc_size(root, 0x7fffffff);
	torture_assert("misc", !p1, "failed: large talloc allowed\n");

	p1 = talloc_strdup(root, "foo");
	talloc_increase_ref_count(p1);
	talloc_increase_ref_count(p1);
	talloc_increase_ref_count(p1);
	CHECK_BLOCKS("misc", p1, 1);
	CHECK_BLOCKS("misc", root, 2);
	talloc_unlink(NULL, p1);
	CHECK_BLOCKS("misc", p1, 1);
	CHECK_BLOCKS("misc", root, 2);
	talloc_unlink(NULL, p1);
	CHECK_BLOCKS("misc", p1, 1);
	CHECK_BLOCKS("misc", root, 2);
	p2 = talloc_strdup(p1, "foo");
	torture_assert("misc", talloc_unlink(root, p2) == -1,
				   "failed: talloc_unlink() of non-reference context should return -1\n");
	torture_assert("misc", talloc_unlink(p1, p2) == 0,
		"failed: talloc_unlink() of parent should succeed\n");
	talloc_unlink(NULL, p1);
	CHECK_BLOCKS("misc", p1, 1);
	CHECK_BLOCKS("misc", root, 2);

	name = talloc_set_name(p1, "my name is %s", "foo");
	torture_assert_str_equal("misc", talloc_get_name(p1), "my name is foo",
		"failed: wrong name after talloc_set_name(my name is foo)");
	torture_assert_str_equal("misc", talloc_get_name(p1), name,
		"failed: wrong name after talloc_set_name(my name is foo)");
	CHECK_BLOCKS("misc", p1, 2);
	CHECK_BLOCKS("misc", root, 3);

	talloc_set_name_const(p1, NULL);
	torture_assert_str_equal ("misc", talloc_get_name(p1), "UNNAMED",
		"failed: wrong name after talloc_set_name(NULL)");
	CHECK_BLOCKS("misc", p1, 2);
	CHECK_BLOCKS("misc", root, 3);

	torture_assert("misc", talloc_free(NULL) == -1, 
				   "talloc_free(NULL) should give -1\n");

	talloc_set_destructor(p1, fail_destructor);
	torture_assert("misc", talloc_free(p1) == -1, 
		"Failed destructor should cause talloc_free to fail\n");
	talloc_set_destructor(p1, NULL);

	talloc_report(root, stderr);


	p2 = (char *)talloc_zero_size(p1, 20);
	torture_assert("misc", p2[19] == 0, "Failed to give zero memory\n");
	talloc_free(p2);

	torture_assert("misc", talloc_strdup(root, NULL) == NULL,
		"failed: strdup on NULL should give NULL\n");

	p2 = talloc_strndup(p1, "foo", 2);
	torture_assert("misc", strcmp("fo", p2) == 0, 
				   "strndup doesn't work\n");
	p2 = talloc_asprintf_append_buffer(p2, "o%c", 'd');
	torture_assert("misc", strcmp("food", p2) == 0, 
				   "talloc_asprintf_append_buffer doesn't work\n");
	CHECK_BLOCKS("misc", p2, 1);
	CHECK_BLOCKS("misc", p1, 3);

	p2 = talloc_asprintf_append_buffer(NULL, "hello %s", "world");
	torture_assert("misc", strcmp("hello world", p2) == 0,
		"talloc_asprintf_append_buffer doesn't work\n");
	CHECK_BLOCKS("misc", p2, 1);
	CHECK_BLOCKS("misc", p1, 3);
	talloc_free(p2);

	d = talloc_array(p1, double, 0x20000000);
	torture_assert("misc", !d, "failed: integer overflow not detected\n");

	d = talloc_realloc(p1, d, double, 0x20000000);
	torture_assert("misc", !d, "failed: integer overflow not detected\n");

	talloc_free(p1);
	CHECK_BLOCKS("misc", root, 1);

	p1 = talloc_named(root, 100, "%d bytes", 100);
	CHECK_BLOCKS("misc", p1, 2);
	CHECK_BLOCKS("misc", root, 3);
	talloc_unlink(root, p1);

	p1 = talloc_init("%d bytes", 200);
	p2 = talloc_asprintf(p1, "my test '%s'", "string");
	torture_assert_str_equal("misc", p2, "my test 'string'",
		"failed: talloc_asprintf(\"my test '%%s'\", \"string\") gave: \"%s\"");
	CHECK_BLOCKS("misc", p1, 3);
	CHECK_SIZE("misc", p2, 17);
	CHECK_BLOCKS("misc", root, 1);
	talloc_unlink(NULL, p1);

	p1 = talloc_named_const(root, 10, "p1");
	p2 = (char *)talloc_named_const(root, 20, "p2");
	(void)talloc_reference(p1, p2);
	talloc_report_full(root, stderr);
	talloc_unlink(root, p2);
	talloc_report_full(root, stderr);
	CHECK_BLOCKS("misc", p2, 1);
	CHECK_BLOCKS("misc", p1, 2);
	CHECK_BLOCKS("misc", root, 3);
	talloc_unlink(p1, p2);
	talloc_unlink(root, p1);

	p1 = talloc_named_const(root, 10, "p1");
	p2 = (char *)talloc_named_const(root, 20, "p2");
	(void)talloc_reference(NULL, p2);
	talloc_report_full(root, stderr);
	talloc_unlink(root, p2);
	talloc_report_full(root, stderr);
	CHECK_BLOCKS("misc", p2, 1);
	CHECK_BLOCKS("misc", p1, 1);
	CHECK_BLOCKS("misc", root, 2);
	talloc_unlink(NULL, p2);
	talloc_unlink(root, p1);

	/* Test that talloc_unlink is a no-op */

	torture_assert("misc", talloc_unlink(root, NULL) == -1,
		"failed: talloc_unlink(root, NULL) == -1\n");

	talloc_report(root, stderr);
	talloc_report(NULL, stderr);

	CHECK_SIZE("misc", root, 0);

	talloc_free(root);

	CHECK_SIZE("misc", NULL, 0);

	talloc_enable_null_tracking_no_autofree();
	talloc_enable_leak_report();
	talloc_enable_leak_report_full();

	printf("success: misc\n");

	return true;
}
Example #27
0
static NTSTATUS idmap_ldap_sids_to_unixids(struct idmap_domain *dom,
					   struct id_map **ids)
{
	LDAPMessage *entry = NULL;
	NTSTATUS ret;
	TALLOC_CTX *memctx;
	struct idmap_ldap_context *ctx;
	LDAPMessage *result = NULL;
	const char *uidNumber;
	const char *gidNumber;
	const char **attr_list;
	char *filter = NULL;
	bool multi = False;
	int idx = 0;
	int bidx = 0;
	int count;
	int rc;
	int i;

	/* Only do query if we are online */
	if (idmap_is_offline())	{
		return NT_STATUS_FILE_IS_OFFLINE;
	}

	ctx = talloc_get_type(dom->private_data, struct idmap_ldap_context);

	memctx = talloc_new(ctx);
	if ( ! memctx) {
		DEBUG(0, ("Out of memory!\n"));
		return NT_STATUS_NO_MEMORY;
	}

	uidNumber = get_attr_key2string(idpool_attr_list, LDAP_ATTR_UIDNUMBER);
	gidNumber = get_attr_key2string(idpool_attr_list, LDAP_ATTR_GIDNUMBER);

	attr_list = get_attr_list(memctx, sidmap_attr_list);

	if ( ! ids[1]) {
		/* if we are requested just one mapping use the simple filter */

		filter = talloc_asprintf(memctx, "(&(objectClass=%s)(%s=%s))",
				LDAP_OBJ_IDMAP_ENTRY,
				LDAP_ATTRIBUTE_SID,
				sid_string_talloc(memctx, ids[0]->sid));
		CHECK_ALLOC_DONE(filter);
		DEBUG(10, ("Filter: [%s]\n", filter));
	} else {
		/* multiple mappings */
		multi = True;
	}

	for (i = 0; ids[i]; i++) {
		ids[i]->status = ID_UNKNOWN;
	}

again:
	if (multi) {

		TALLOC_FREE(filter);
		filter = talloc_asprintf(memctx,
					 "(&(objectClass=%s)(|",
					 LDAP_OBJ_IDMAP_ENTRY);
		CHECK_ALLOC_DONE(filter);

		bidx = idx;
		for (i = 0; (i < IDMAP_LDAP_MAX_IDS) && ids[idx]; i++, idx++) {
			filter = talloc_asprintf_append_buffer(filter, "(%s=%s)",
					LDAP_ATTRIBUTE_SID,
					sid_string_talloc(memctx,
							  ids[idx]->sid));
			CHECK_ALLOC_DONE(filter);
		}
		filter = talloc_asprintf_append_buffer(filter, "))");
		CHECK_ALLOC_DONE(filter);
		DEBUG(10, ("Filter: [%s]", filter));
	} else {
		bidx = 0;
		idx = 1;
	}

	rc = smbldap_search(ctx->smbldap_state, ctx->suffix, LDAP_SCOPE_SUBTREE,
		filter, attr_list, 0, &result);

	if (rc != LDAP_SUCCESS) {
		DEBUG(3,("Failure looking up sids (%s)\n",
			 ldap_err2string(rc)));
		ret = NT_STATUS_UNSUCCESSFUL;
		goto done;
	}

	count = ldap_count_entries(ctx->smbldap_state->ldap_struct, result);

	if (count == 0) {
		DEBUG(10, ("NO SIDs found\n"));
	}

	for (i = 0; i < count; i++) {
		char *sidstr = NULL;
		char *tmp = NULL;
		enum id_type type;
		struct id_map *map;
		struct dom_sid sid;
		uint32_t id;

		if (i == 0) { /* first entry */
			entry = ldap_first_entry(ctx->smbldap_state->ldap_struct,
						 result);
		} else { /* following ones */
			entry = ldap_next_entry(ctx->smbldap_state->ldap_struct,
						entry);
		}
		if ( ! entry) {
			DEBUG(2, ("ERROR: Unable to fetch ldap entries "
				  "from results\n"));
			break;
		}

		/* first check if the SID is present */
		sidstr = smbldap_talloc_single_attribute(
				ctx->smbldap_state->ldap_struct,
				entry, LDAP_ATTRIBUTE_SID, memctx);
		if ( ! sidstr) { /* no sid ??, skip entry */
			DEBUG(2, ("WARNING SID not found on entry\n"));
			continue;
		}

		if ( ! string_to_sid(&sid, sidstr)) {
			DEBUG(2, ("ERROR: Invalid SID on entry\n"));
			TALLOC_FREE(sidstr);
			continue;
		}

		map = idmap_find_map_by_sid(&ids[bidx], &sid);
		if (!map) {
			DEBUG(2, ("WARNING: couldn't find entry sid (%s) "
				  "in ids", sidstr));
			TALLOC_FREE(sidstr);
			continue;
		}

		/* now try to see if it is a uid, if not try with a gid
		 * (gid is more common, but in case both uidNumber and
		 * gidNumber are returned the SID is mapped to the uid
		 * not the gid) */
		type = ID_TYPE_UID;
		tmp = smbldap_talloc_single_attribute(
				ctx->smbldap_state->ldap_struct,
				entry, uidNumber, memctx);
		if ( ! tmp) {
			type = ID_TYPE_GID;
			tmp = smbldap_talloc_single_attribute(
					ctx->smbldap_state->ldap_struct,
					entry, gidNumber, memctx);
		}
		if ( ! tmp) { /* no ids ?? */
			DEBUG(5, ("no uidNumber, "
				  "nor gidNumber attributes found\n"));
			TALLOC_FREE(sidstr);
			continue;
		}

		id = strtoul(tmp, NULL, 10);
		if (!idmap_unix_id_is_in_range(id, dom)) {
			DEBUG(5, ("Requested id (%u) out of range (%u - %u). "
				  "Filtered!\n", id,
				  dom->low_id, dom->high_id));
			TALLOC_FREE(sidstr);
			TALLOC_FREE(tmp);
			continue;
		}
		TALLOC_FREE(tmp);

		if (map->status == ID_MAPPED) {
			DEBUG(1, ("WARNING: duplicate %s mapping in LDAP. "
			      "overwriting mapping %s -> %u with %s -> %u\n",
			      (type == ID_TYPE_UID) ? "UID" : "GID",
			      sidstr, map->xid.id, sidstr, id));
		}

		TALLOC_FREE(sidstr);

		/* mapped */
		map->xid.type = type;
		map->xid.id = id;
		map->status = ID_MAPPED;

		DEBUG(10, ("Mapped %s -> %lu (%d)\n", sid_string_dbg(map->sid),
			   (unsigned long)map->xid.id, map->xid.type));
	}

	/* free the ldap results */
	if (result) {
		ldap_msgfree(result);
		result = NULL;
	}

	if (multi && ids[idx]) { /* still some values to map */
		goto again;
	}

	/*
	 *  try to create new mappings for unmapped sids
	 */
	for (i = 0; ids[i]; i++) {
		if (ids[i]->status != ID_MAPPED) {
			ids[i]->status = ID_UNMAPPED;
			if (ids[i]->sid != NULL) {
				ret = idmap_ldap_new_mapping(dom, ids[i]);
				if (!NT_STATUS_IS_OK(ret)) {
					goto done;
				}
			}
		}
	}

	ret = NT_STATUS_OK;

done:
	talloc_free(memctx);
	return ret;
}
Example #28
0
/** Convert multiple group names into a DNs
 *
 * Given an array of group names, builds a filter matching all names, then retrieves all group objects
 * and stores the DN associated with each group object.
 *
 * @param[in] inst rlm_ldap configuration.
 * @param[in] request Current request.
 * @param[in,out] pconn to use. May change as this function calls functions which auto re-connect.
 * @param[in] names to covert to DNs (NULL terminated).
 * @param[out] out Where to write the DNs. DNs must be freed with ldap_memfree(). Will be NULL terminated.
 * @param[in] outlen Size of out.
 * @return One of the RLM_MODULE_* values.
 */
static rlm_rcode_t rlm_ldap_group_name2dn(ldap_instance_t const *inst, REQUEST *request, ldap_handle_t **pconn,
					  char **names, char **out, size_t outlen)
{
	rlm_rcode_t rcode = RLM_MODULE_OK;
	ldap_rcode_t status;
	int ldap_errno;

	unsigned int name_cnt = 0;
	unsigned int entry_cnt;
	char const *attrs[] = { NULL };

	LDAPMessage *result = NULL, *entry;

	char **name = names;
	char **dn = out;
	char buffer[LDAP_MAX_GROUP_NAME_LEN + 1];

	char *filter;

	*dn = NULL;

	if (!*names) {
		return RLM_MODULE_OK;
	}

	if (!inst->groupobj_name_attr) {
		REDEBUG("Told to convert group names to DNs but missing 'group.name_attribute' directive");

		return RLM_MODULE_INVALID;
	}

	RDEBUG("Converting group name(s) to group DN(s)");

	/*
	 *	It'll probably only save a few ms in network latency, but it means we can send a query
	 *	for the entire group list at once.
	 */
	filter = talloc_asprintf(request, "%s%s%s",
				 inst->groupobj_filter ? "(&" : "",
				 inst->groupobj_filter ? inst->groupobj_filter : "",
				 names[0] && names[1] ? "(|" : "");
	while (*name) {
		rlm_ldap_escape_func(request, buffer, sizeof(buffer), *name++, NULL);
		filter = talloc_asprintf_append_buffer(filter, "(%s=%s)", inst->groupobj_name_attr, buffer);

		name_cnt++;
	}
	filter = talloc_asprintf_append_buffer(filter, "%s%s",
					       inst->groupobj_filter ? ")" : "",
					       names[0] && names[1] ? ")" : "");

	status = rlm_ldap_search(inst, request, pconn, inst->groupobj_base_dn, inst->groupobj_scope,
				 filter, attrs, &result);
	switch (status) {
		case LDAP_PROC_SUCCESS:
			break;
		case LDAP_PROC_NO_RESULT:
			RDEBUG("Tried to resolve group name(s) to DNs but got no results");
			goto finish;
		default:
			rcode = RLM_MODULE_FAIL;
			goto finish;
	}

	entry_cnt = ldap_count_entries((*pconn)->handle, result);
	if (entry_cnt > name_cnt) {
		REDEBUG("Number of DNs exceeds number of names, group and/or dn should be more restrictive");
		rcode = RLM_MODULE_INVALID;

		goto finish;
	}

	if (entry_cnt > (outlen - 1)) {
		REDEBUG("Number of DNs exceeds limit (%zu)", outlen - 1);
		rcode = RLM_MODULE_INVALID;

		goto finish;
	}

	if (entry_cnt < name_cnt) {
		RWDEBUG("Got partial mapping of group names (%i) to DNs (%i), membership information may be incomplete",
			name_cnt, entry_cnt);
	}

	entry = ldap_first_entry((*pconn)->handle, result);
	if (!entry) {
		ldap_get_option((*pconn)->handle, LDAP_OPT_RESULT_CODE, &ldap_errno);
		REDEBUG("Failed retrieving entry: %s", ldap_err2string(ldap_errno));

		rcode = RLM_MODULE_FAIL;
		goto finish;
	}

	do {
		*dn = ldap_get_dn((*pconn)->handle, entry);
		RDEBUG("Got group DN \"%s\"", *dn);
		dn++;
	} while((entry = ldap_next_entry((*pconn)->handle, entry)));

	*dn = NULL;

	finish:
	talloc_free(filter);
	if (result) {
		ldap_msgfree(result);
	}

	/*
	 *	Be nice and cleanup the output array if we error out.
	 */
	if (rcode != RLM_MODULE_OK) {
		dn = out;
		while(*dn) ldap_memfree(*dn++);
		*dn = NULL;
	}

	return rcode;
}
Example #29
0
static void manage_gensec_request(enum stdio_helper_mode stdio_helper_mode, 
				  struct loadparm_context *lp_ctx,
				  char *buf, int length, void **private1,
				  unsigned int mux_id, void **private2) 
{
	DATA_BLOB in;
	DATA_BLOB out = data_blob(NULL, 0);
	char *out_base64 = NULL;
	const char *reply_arg = NULL;
	struct gensec_ntlm_state {
		struct gensec_security *gensec_state;
		const char *set_password;
	};
	struct gensec_ntlm_state *state;
	struct tevent_context *ev;
	struct imessaging_context *msg;

	NTSTATUS nt_status;
	bool first = false;
	const char *reply_code;
	struct cli_credentials *creds;

	static char *want_feature_list = NULL;
	static DATA_BLOB session_key;

	TALLOC_CTX *mem_ctx;

	if (*private1) {
		state = (struct gensec_ntlm_state *)*private1;
	} else {
		state = talloc_zero(NULL, struct gensec_ntlm_state);
		if (!state) {
			mux_printf(mux_id, "BH No Memory\n");
			exit(1);
		}
		*private1 = state;
		if (opt_password) {
			state->set_password = opt_password;
		}
	}
	
	if (strlen(buf) < 2) {
		DEBUG(1, ("query [%s] invalid", buf));
		mux_printf(mux_id, "BH Query invalid\n");
		return;
	}

	if (strlen(buf) > 3) {
		if(strncmp(buf, "SF ", 3) == 0) {
			DEBUG(10, ("Setting flags to negotiate\n"));
			talloc_free(want_feature_list);
			want_feature_list = talloc_strndup(state, buf+3, strlen(buf)-3);
			mux_printf(mux_id, "OK\n");
			return;
		}
		in = base64_decode_data_blob(buf + 3);
	} else {
		in = data_blob(NULL, 0);
	}

	if (strncmp(buf, "YR", 2) == 0) {
		if (state->gensec_state) {
			talloc_free(state->gensec_state);
			state->gensec_state = NULL;
		}
	} else if ( (strncmp(buf, "OK", 2) == 0)) {
		/* Just return BH, like ntlm_auth from Samba 3 does. */
		mux_printf(mux_id, "BH Command expected\n");
		data_blob_free(&in);
		return;
	} else if ( (strncmp(buf, "TT ", 3) != 0) &&
		    (strncmp(buf, "KK ", 3) != 0) &&
		    (strncmp(buf, "AF ", 3) != 0) &&
		    (strncmp(buf, "NA ", 3) != 0) && 
		    (strncmp(buf, "UG", 2) != 0) && 
		    (strncmp(buf, "PW ", 3) != 0) &&
		    (strncmp(buf, "GK", 2) != 0) &&
		    (strncmp(buf, "GF", 2) != 0)) {
		DEBUG(1, ("SPNEGO request [%s] invalid\n", buf));
		mux_printf(mux_id, "BH SPNEGO request invalid\n");
		data_blob_free(&in);
		return;
	}

	ev = s4_event_context_init(state);
	if (!ev) {
		exit(1);
	}

	mem_ctx = talloc_named(NULL, 0, "manage_gensec_request internal mem_ctx");

	/* setup gensec */
	if (!(state->gensec_state)) {
		switch (stdio_helper_mode) {
		case GSS_SPNEGO_CLIENT:
		case NTLMSSP_CLIENT_1:
			/* setup the client side */

			nt_status = gensec_client_start(NULL, &state->gensec_state, ev, 
							lpcfg_gensec_settings(NULL, lp_ctx));
			if (!NT_STATUS_IS_OK(nt_status)) {
				talloc_free(mem_ctx);
				exit(1);
			}

			break;
		case GSS_SPNEGO_SERVER:
		case SQUID_2_5_NTLMSSP:
		{
			const char *winbind_method[] = { "winbind", NULL };
			struct auth4_context *auth_context;

			msg = imessaging_client_init(state, lpcfg_imessaging_path(state, lp_ctx), ev);
			if (!msg) {
				talloc_free(mem_ctx);
				exit(1);
			}
			nt_status = auth_context_create_methods(mem_ctx, 
								winbind_method,
								ev, 
								msg, 
								lp_ctx,
								NULL,
								&auth_context);
	
			if (!NT_STATUS_IS_OK(nt_status)) {
				talloc_free(mem_ctx);
				exit(1);
			}
			
			if (!NT_STATUS_IS_OK(gensec_server_start(state, ev, 
								 lpcfg_gensec_settings(state, lp_ctx),
								 auth_context, &state->gensec_state))) {
				talloc_free(mem_ctx);
				exit(1);
			}
			break;
		}
		default:
			talloc_free(mem_ctx);
			abort();
		}

		creds = cli_credentials_init(state->gensec_state);
		cli_credentials_set_conf(creds, lp_ctx);
		if (opt_username) {
			cli_credentials_set_username(creds, opt_username, CRED_SPECIFIED);
		}
		if (opt_domain) {
			cli_credentials_set_domain(creds, opt_domain, CRED_SPECIFIED);
		}
		if (state->set_password) {
			cli_credentials_set_password(creds, state->set_password, CRED_SPECIFIED);
		} else {
			cli_credentials_set_password_callback(creds, get_password);
			creds->priv_data = (void*)(uintptr_t)mux_id;
		}
		if (opt_workstation) {
			cli_credentials_set_workstation(creds, opt_workstation, CRED_SPECIFIED);
		}
		
		switch (stdio_helper_mode) {
		case GSS_SPNEGO_SERVER:
		case SQUID_2_5_NTLMSSP:
			cli_credentials_set_machine_account(creds, lp_ctx);
			break;
		default:
			break;
		}

		gensec_set_credentials(state->gensec_state, creds);
		gensec_want_feature_list(state->gensec_state, want_feature_list);

		switch (stdio_helper_mode) {
		case GSS_SPNEGO_CLIENT:
		case GSS_SPNEGO_SERVER:
			nt_status = gensec_start_mech_by_oid(state->gensec_state, GENSEC_OID_SPNEGO);
			if (!in.length) {
				first = true;
			}
			break;
		case NTLMSSP_CLIENT_1:
			if (!in.length) {
				first = true;
			}
			/* fall through */
		case SQUID_2_5_NTLMSSP:
			nt_status = gensec_start_mech_by_oid(state->gensec_state, GENSEC_OID_NTLMSSP);
			break;
		default:
			talloc_free(mem_ctx);
			abort();
		}

		if (!NT_STATUS_IS_OK(nt_status)) {
			DEBUG(1, ("GENSEC mech failed to start: %s\n", nt_errstr(nt_status)));
			mux_printf(mux_id, "BH GENSEC mech failed to start\n");
			talloc_free(mem_ctx);
			return;
		}

	}

	/* update */

	if (strncmp(buf, "PW ", 3) == 0) {
		state->set_password = talloc_strndup(state,
						     (const char *)in.data, 
						     in.length);
		
		cli_credentials_set_password(gensec_get_credentials(state->gensec_state),
					     state->set_password,
					     CRED_SPECIFIED);
		mux_printf(mux_id, "OK\n");
		data_blob_free(&in);
		talloc_free(mem_ctx);
		return;
	}

	if (strncmp(buf, "UG", 2) == 0) {
		int i;
		char *grouplist = NULL;
		struct auth_session_info *session_info;

		nt_status = gensec_session_info(state->gensec_state, mem_ctx, &session_info);
		if (!NT_STATUS_IS_OK(nt_status)) {
			DEBUG(1, ("gensec_session_info failed: %s\n", nt_errstr(nt_status)));
			mux_printf(mux_id, "BH %s\n", nt_errstr(nt_status));
			data_blob_free(&in);
			talloc_free(mem_ctx);
			return;
		}
		
		/* get the string onto the context */
		grouplist = talloc_strdup(mem_ctx, "");
		
		for (i=0; i<session_info->security_token->num_sids; i++) {
			struct security_token *token = session_info->security_token; 
			const char *sidstr = dom_sid_string(session_info, 
							    &token->sids[i]);
			grouplist = talloc_asprintf_append_buffer(grouplist, "%s,", sidstr);
		}

		mux_printf(mux_id, "GL %s\n", grouplist);
		talloc_free(session_info);
		data_blob_free(&in);
		talloc_free(mem_ctx);
		return;
	}

	if (strncmp(buf, "GK", 2) == 0) {
		char *base64_key;
		DEBUG(10, ("Requested session key\n"));
		nt_status = gensec_session_key(state->gensec_state, mem_ctx, &session_key);
		if(!NT_STATUS_IS_OK(nt_status)) {
			DEBUG(1, ("gensec_session_key failed: %s\n", nt_errstr(nt_status)));
			mux_printf(mux_id, "BH No session key\n");
			talloc_free(mem_ctx);
			return;
		} else {
			base64_key = base64_encode_data_blob(state, session_key);
			mux_printf(mux_id, "GK %s\n", base64_key);
			talloc_free(base64_key);
		}
		talloc_free(mem_ctx);
		return;
	}

	if (strncmp(buf, "GF", 2) == 0) {
		struct ntlmssp_state *ntlmssp_state;
		uint32_t neg_flags;

		ntlmssp_state = talloc_get_type(state->gensec_state->private_data,
				struct ntlmssp_state);
		neg_flags = ntlmssp_state->neg_flags;

		DEBUG(10, ("Requested negotiated feature flags\n"));
		mux_printf(mux_id, "GF 0x%08x\n", neg_flags);
		return;
	}

	nt_status = gensec_update(state->gensec_state, mem_ctx, in, &out);
	
	/* don't leak 'bad password'/'no such user' info to the network client */
	nt_status = nt_status_squash(nt_status);

	if (out.length) {
		out_base64 = base64_encode_data_blob(mem_ctx, out);
	} else {
		out_base64 = NULL;
	}

	if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
		reply_arg = "*";
		if (first) {
			reply_code = "YR";
		} else if (state->gensec_state->gensec_role == GENSEC_CLIENT) { 
			reply_code = "KK";
		} else if (state->gensec_state->gensec_role == GENSEC_SERVER) { 
			reply_code = "TT";
		} else {
			abort();
		}


	} else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_ACCESS_DENIED)) {
		reply_code = "BH NT_STATUS_ACCESS_DENIED";
		reply_arg = nt_errstr(nt_status);
		DEBUG(1, ("GENSEC login failed: %s\n", nt_errstr(nt_status)));
	} else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_UNSUCCESSFUL)) {
		reply_code = "BH NT_STATUS_UNSUCCESSFUL";
		reply_arg = nt_errstr(nt_status);
		DEBUG(1, ("GENSEC login failed: %s\n", nt_errstr(nt_status)));
	} else if (!NT_STATUS_IS_OK(nt_status)) {
		reply_code = "NA";
		reply_arg = nt_errstr(nt_status);
		DEBUG(1, ("GENSEC login failed: %s\n", nt_errstr(nt_status)));
	} else if /* OK */ (state->gensec_state->gensec_role == GENSEC_SERVER) {
		struct auth_session_info *session_info;

		nt_status = gensec_session_info(state->gensec_state, mem_ctx, &session_info);
		if (!NT_STATUS_IS_OK(nt_status)) {
			reply_code = "BH Failed to retrive session info";
			reply_arg = nt_errstr(nt_status);
			DEBUG(1, ("GENSEC failed to retrieve the session info: %s\n", nt_errstr(nt_status)));
		} else {

			reply_code = "AF";
			reply_arg = talloc_asprintf(state->gensec_state, 
						    "%s%s%s", session_info->info->domain_name,
						    lpcfg_winbind_separator(lp_ctx), session_info->info->account_name);
			talloc_free(session_info);
		}
	} else if (state->gensec_state->gensec_role == GENSEC_CLIENT) {
		reply_code = "AF";
		reply_arg = out_base64;
	} else {
		abort();
	}

	switch (stdio_helper_mode) {
	case GSS_SPNEGO_SERVER:
		mux_printf(mux_id, "%s %s %s\n", reply_code, 
			  out_base64 ? out_base64 : "*", 
			  reply_arg ? reply_arg : "*");
		break;
	default:
		if (out_base64) {
			mux_printf(mux_id, "%s %s\n", reply_code, out_base64);
		} else if (reply_arg) {
			mux_printf(mux_id, "%s %s\n", reply_code, reply_arg);
		} else {
			mux_printf(mux_id, "%s\n", reply_code);
		}
	}

	talloc_free(mem_ctx);
	return;
}
Example #30
0
/** Serialize a cache entry as a humanly readable string
 *
 * @param ctx to alloc new string in. Should be a talloc pool a little bigger
 *	than the maximum serialized size of the entry.
 * @param out Where to write pointer to serialized cache entry.
 * @param c Cache entry to serialize.
 * @return 0 on success else -1.
 */
int cache_serialize(TALLOC_CTX *ctx, char **out, rlm_cache_entry_t *c)
{
	TALLOC_CTX *pairs = NULL;

	vp_cursor_t cursor;
	VALUE_PAIR *vp;

	char *to_store = NULL, *pair;

	to_store = talloc_asprintf(ctx, "&Cache-Expires = %" PRIu64 "\n&Cache-Created = %" PRIu64 "\n",
				   (uint64_t)c->expires, (uint64_t)c->created);
	if (!to_store) goto error;

	/*
	 *	It's valid to have an empty cache entry (save allocing the
	 *	pairs pool)
	 */
	if (!c->control && !c->packet && !c->reply) goto finish;

	/*
	 *  In the majority of cases using these pools reduces the number of mallocs
	 *  to two, except in the case where the total serialized pairs length is
	 *  greater than the pairs pool, or the total serialized string is greater
	 *  than the store pool.
	 */
	pairs = talloc_pool(ctx, 512);
	if (!pairs) {
	error:
		talloc_free(pairs);
		return -1;
	}

	if (c->control) {
		for (vp = fr_cursor_init(&cursor, &c->control);
		     vp;
		     vp = fr_cursor_next(&cursor)) {
			pair = vp_aprints(pairs, vp, '\'');
			if (!pair) goto error;

			to_store = talloc_asprintf_append_buffer(to_store, "&control:%s\n", pair);
			if (!to_store) goto error;
		}
	}

	if (c->packet) {
		for (vp = fr_cursor_init(&cursor, &c->packet);
		     vp;
		     vp = fr_cursor_next(&cursor)) {
			pair = vp_aprints(pairs, vp, '\'');
			if (!pair) goto error;

			to_store = talloc_asprintf_append_buffer(to_store, "&%s\n", pair);
			if (!to_store) goto error;
		}
	}

	if (c->reply) {
		for (vp = fr_cursor_init(&cursor, &c->reply);
		     vp;
		     vp = fr_cursor_next(&cursor)) {
			pair = vp_aprints(pairs, vp, '\'');
			if (!pair) goto error;

			to_store = talloc_asprintf_append_buffer(to_store, "&reply:%s\n", pair);
			if (!to_store) goto error;
		}
	}

finish:
	talloc_free(pairs);
	*out = to_store;

	return 0;
}