Beispiel #1
0
_PUBLIC_ int cli_credentials_set_ccache(struct cli_credentials *cred, 
					struct loadparm_context *lp_ctx,
					const char *name,
					enum credentials_obtained obtained,
					const char **error_string)
{
	krb5_error_code ret;
	krb5_principal princ;
	struct ccache_container *ccc;
	if (cred->ccache_obtained > obtained) {
		return 0;
	}

	ccc = talloc(cred, struct ccache_container);
	if (!ccc) {
		(*error_string) = error_message(ENOMEM);
		return ENOMEM;
	}

	ret = cli_credentials_get_krb5_context(cred, lp_ctx,
					       &ccc->smb_krb5_context);
	if (ret) {
		(*error_string) = error_message(ret);
		talloc_free(ccc);
		return ret;
	}
	if (!talloc_reference(ccc, ccc->smb_krb5_context)) {
		talloc_free(ccc);
		(*error_string) = error_message(ENOMEM);
		return ENOMEM;
	}

	if (name) {
		ret = krb5_cc_resolve(ccc->smb_krb5_context->krb5_context, name, &ccc->ccache);
		if (ret) {
			(*error_string) = talloc_asprintf(cred, "failed to read krb5 ccache: %s: %s\n",
							  name,
							  smb_get_krb5_error_message(ccc->smb_krb5_context->krb5_context,
										     ret, ccc));
			talloc_free(ccc);
			return ret;
		}
	} else {
		ret = krb5_cc_default(ccc->smb_krb5_context->krb5_context, &ccc->ccache);
		if (ret) {
			(*error_string) = talloc_asprintf(cred, "failed to read default krb5 ccache: %s\n",
							  smb_get_krb5_error_message(ccc->smb_krb5_context->krb5_context,
										     ret, ccc));
			talloc_free(ccc);
			return ret;
		}
	}

	talloc_set_destructor(ccc, free_dccache);

	ret = krb5_cc_get_principal(ccc->smb_krb5_context->krb5_context, ccc->ccache, &princ);

	if (ret == 0) {
		krb5_free_principal(ccc->smb_krb5_context->krb5_context, princ);
		ret = cli_credentials_set_from_ccache(cred, ccc, obtained, error_string);

		if (ret) {
			(*error_string) = error_message(ret);
			return ret;
		}

		cred->ccache = ccc;
		cred->ccache_obtained = obtained;
		talloc_steal(cred, ccc);

		cli_credentials_invalidate_client_gss_creds(cred, cred->ccache_obtained);
		return 0;
	}
	return 0;
}
Beispiel #2
0
static int config(struct vf_instance *vf,
                  int width, int height, int d_width, int d_height,
                  unsigned int flags, unsigned int fmt)
{
    vf->priv->filter.in_width = width;
    vf->priv->filter.in_height = height;
    vf->priv->filter.in_d_width = d_width;
    vf->priv->filter.in_d_height = d_height;
    vf->priv->filter.in_fmt = imgfmt_to_name(fmt);
    vf->priv->filter.out_width = width;
    vf->priv->filter.out_height = height;
    vf->priv->filter.out_d_width = d_width;
    vf->priv->filter.out_d_height = d_height;
    vf->priv->filter.out_fmt = NULL;
    vf->priv->filter.out_cnt = 1;

    if (!vf->priv->filter.in_fmt) {
        mp_msg(MSGT_VFILTER, MSGL_ERR, "invalid input/output format\n");
        return 0;
    }
    if (vf->priv->filter.config && vf->priv->filter.config(&vf->priv->filter) < 0) {
        mp_msg(MSGT_VFILTER, MSGL_ERR, "filter config failed\n");
        return 0;
    }

    // copy away stuff to sanity island
    vf->priv->out_cnt = vf->priv->filter.out_cnt;
    vf->priv->out_width = vf->priv->filter.out_width;
    vf->priv->out_height = vf->priv->filter.out_height;

    if (vf->priv->filter.out_fmt)
        vf->priv->outfmt = name_to_imgfmt(vf->priv->filter.out_fmt);
    else {
        struct vf_dlopen_formatpair *p = vf->priv->filter.format_mapping;
        vf->priv->outfmt = 0;
        if (p) {
            for (; p->from; ++p) {
                // TODO support pixel format classes in matching
                if (!strcmp(p->from, vf->priv->filter.in_fmt)) {
                    vf->priv->outfmt = name_to_imgfmt(p->to);
                    break;
                }
            }
        } else
            vf->priv->outfmt = fmt;
        vf->priv->filter.out_fmt = imgfmt_to_name(vf->priv->outfmt);
    }

    if (!vf->priv->outfmt) {
        mp_msg(MSGT_VFILTER, MSGL_ERR,
               "filter config wants an unsupported output format\n");
        return 0;
    }
    if (!vf->priv->out_cnt || vf->priv->out_cnt > FILTER_MAX_OUTCNT) {
        mp_msg(MSGT_VFILTER, MSGL_ERR,
               "filter config wants to yield zero or too many output frames\n");
        return 0;
    }

    for (int i = 0; i < vf->priv->out_cnt; ++i) {
        talloc_free(vf->priv->outpic[i]);
        vf->priv->outpic[i] =
            mp_image_alloc(vf->priv->out_width, vf->priv->out_height,
                           vf->priv->outfmt);
        set_imgprop(&vf->priv->filter.outpic[i], vf->priv->outpic[i]);
        talloc_steal(vf, vf->priv->outpic[i]);
    }

    return vf_next_config(vf, vf->priv->out_width,
                          vf->priv->out_height,
                          vf->priv->filter.out_d_width,
                          vf->priv->filter.out_d_height,
                          flags, vf->priv->outfmt);
}
Beispiel #3
0
krb5_error_code smb_krb5_update_keytab(TALLOC_CTX *parent_ctx,
				krb5_context context,
				const char *keytab_name,
				const char *samAccountName,
				const char *realm,
				const char **SPNs,
				int num_SPNs,
				const char *saltPrincipal,
				const char *new_secret,
				const char *old_secret,
				int kvno,
				uint32_t supp_enctypes,
				bool delete_all_kvno,
			        krb5_keytab *_keytab,
				const char **error_string)
{
	krb5_keytab keytab;
	krb5_error_code ret;
	bool found_previous;
	TALLOC_CTX *tmp_ctx;
	krb5_principal *principals = NULL;

	if (keytab_name == NULL) {
		return ENOENT;
	}

	ret = krb5_kt_resolve(context, keytab_name, &keytab);
	if (ret) {
		*error_string = smb_get_krb5_error_message(context,
							   ret, parent_ctx);
		return ret;
	}

	DEBUG(5, ("Opened keytab %s\n", keytab_name));

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

	/* Get the principal we will store the new keytab entries under */
	ret = principals_from_list(tmp_ctx,
				  samAccountName, realm, SPNs, num_SPNs,
				  context, &principals, error_string);

	if (ret != 0) {
		*error_string = talloc_asprintf(parent_ctx,
			"Failed to load principals from ldb message: %s\n",
			*error_string);
		goto done;
	}

	ret = remove_old_entries(tmp_ctx, kvno, principals, delete_all_kvno,
				 context, keytab, &found_previous, error_string);
	if (ret != 0) {
		*error_string = talloc_asprintf(parent_ctx,
			"Failed to remove old principals from keytab: %s\n",
			*error_string);
		goto done;
	}

	if (!delete_all_kvno) {
		/* Create a new keytab.  If during the cleanout we found
		 * entires for kvno -1, then don't try and duplicate them.
		 * Otherwise, add kvno, and kvno -1 */

		ret = create_keytab(tmp_ctx,
				    samAccountName, realm, saltPrincipal,
				    kvno, new_secret, old_secret,
				    supp_enctypes, principals,
				    context, keytab,
				    found_previous ? false : true,
				    error_string);
		if (ret) {
			talloc_steal(parent_ctx, *error_string);
		}
	}

	if (ret == 0 && _keytab != NULL) {
		/* caller wants the keytab handle back */
		*_keytab = keytab;
	}

done:
	keytab_principals_free(context, principals);
	if (ret != 0 || _keytab == NULL) {
		krb5_kt_close(context, keytab);
	}
	talloc_free(tmp_ctx);
	return ret;
}
Beispiel #4
0
/**
   \details Establishes a new Session Context with the server on the
   exchange_emsmdb pipe

   \param parent_mem_ctx pointer to the memory context
   \param session pointer to the MAPI session context
   \param p pointer to the DCERPC pipe
   \param cred pointer to the user credentials
   \param return_value pointer on EcDoConnect MAPI return value

   \return an allocated emsmdb_context on success, otherwise NULL
 */
struct emsmdb_context *emsmdb_connect(TALLOC_CTX *parent_mem_ctx, 
				      struct mapi_session *session,
				      struct dcerpc_pipe *p, 
				      struct cli_credentials *cred,
				      int *return_value)
{
	TALLOC_CTX		*mem_ctx;
	struct EcDoConnect	r;
	struct emsmdb_context	*ret;
	NTSTATUS		status;
	enum MAPISTATUS		retval;
	uint32_t		pullTimeStamp = 0;

	/* Sanity Checks */
	if (!session) return NULL;
	if (!p) return NULL;
	if (!cred) return NULL;
	if (!return_value) return NULL;
	if (!session->profile->mailbox) return NULL;

	mem_ctx = talloc_named(parent_mem_ctx, 0, "emsmdb_connect");

	ret = talloc_zero(parent_mem_ctx, struct emsmdb_context);
	ret->rpc_connection = p;
	ret->mem_ctx = parent_mem_ctx;

	ret->cache_requests = talloc(parent_mem_ctx, struct EcDoRpc_MAPI_REQ *);
	ret->info.szDisplayName = NULL;
	ret->info.szDNPrefix = NULL;

	r.in.szUserDN = session->profile->mailbox;
	r.in.ulFlags = 0x00000000;
	r.in.ulConMod = emsmdb_hash(r.in.szUserDN);
	r.in.cbLimit = 0x00000000;
	r.in.ulCpid = session->profile->codepage;
	r.in.ulLcidString = session->profile->language;
	r.in.ulLcidSort = session->profile->method;
	r.in.ulIcxrLink = 0xFFFFFFFF;
	r.in.usFCanConvertCodePages = 0x1;
	r.in.rgwClientVersion[0] = 0x000c;
	r.in.rgwClientVersion[1] = 0x183e;
	r.in.rgwClientVersion[2] = 0x03e8;
	r.in.pullTimeStamp = &pullTimeStamp;

	r.out.szDNPrefix = (const char **)&ret->info.szDNPrefix;
	r.out.szDisplayName = (const char **)&ret->info.szDisplayName;
	r.out.handle = &ret->handle;
	r.out.pcmsPollsMax = &ret->info.pcmsPollsMax;
	r.out.pcRetry = &ret->info.pcRetry;
	r.out.pcmsRetryDelay = &ret->info.pcmsRetryDelay;
	r.out.picxr = &ret->info.picxr;
	r.out.pullTimeStamp = &pullTimeStamp;

	status = dcerpc_EcDoConnect_r(p->binding_handle, mem_ctx, &r);
	retval = r.out.result;
	if (!NT_STATUS_IS_OK(status) || retval) {
		*return_value = retval;
		mapi_errstr("EcDoConnect", retval);
		talloc_free(mem_ctx);
		return NULL;
	}

	ret->info.szDNPrefix = talloc_steal(parent_mem_ctx, ret->info.szDNPrefix);
	ret->info.szDisplayName = talloc_steal(parent_mem_ctx, ret->info.szDisplayName);

	ret->info.rgwServerVersion[0] = r.out.rgwServerVersion[0];
	ret->info.rgwServerVersion[1] = r.out.rgwServerVersion[1];
	ret->info.rgwServerVersion[2] = r.out.rgwServerVersion[2];

	ret->cred = cred;
	ret->max_data = 0xFFF0;
	ret->setup = false;

	talloc_free(mem_ctx);

	return ret;
}
Beispiel #5
0
void mp_handle_nav(struct MPContext *mpctx)
{
    struct mp_nav_state *nav = mpctx->nav_state;
    if (!nav)
        return;
    while (1) {
        struct mp_nav_event *ev = NULL;
        stream_control(mpctx->stream, STREAM_CTRL_GET_NAV_EVENT, &ev);
        if (!ev)
            break;
        switch (ev->event) {
        case MP_NAV_EVENT_DRAIN: {
            nav->nav_draining = true;
            MP_VERBOSE(nav, "drain requested\n");
            break;
        }
        case MP_NAV_EVENT_RESET_ALL: {
            mpctx->stop_play = PT_RELOAD_DEMUXER;
            MP_VERBOSE(nav, "reload\n");
            // return immediately.
            // other events should be handled after reloaded.
            talloc_free(ev);
            return;
        }
        case MP_NAV_EVENT_RESET: {
            nav->nav_still_frame = 0;
            break;
        }
        case MP_NAV_EVENT_EOF:
            nav->nav_eof = true;
            break;
        case MP_NAV_EVENT_STILL_FRAME: {
            int len = ev->u.still_frame.seconds;
            MP_VERBOSE(nav, "wait for %d seconds\n", len);
            if (len > 0 && nav->nav_still_frame == 0)
                nav->nav_still_frame = len;
            break;
        }
        case MP_NAV_EVENT_MENU_MODE:
            nav->nav_menu = ev->u.menu_mode.enable;
            if (nav->nav_menu) {
                mp_input_enable_section(mpctx->input, "discnav-menu",
                                        MP_INPUT_ON_TOP);
            } else {
                mp_input_disable_section(mpctx->input, "discnav-menu");
            }
            break;
        case MP_NAV_EVENT_HIGHLIGHT: {
            MP_VERBOSE(nav, "highlight: %d %d %d - %d %d\n",
                       ev->u.highlight.display,
                       ev->u.highlight.sx, ev->u.highlight.sy,
                       ev->u.highlight.ex, ev->u.highlight.ey);
            osd_set_nav_highlight(mpctx->osd, NULL);
            nav->highlight[0] = ev->u.highlight.sx;
            nav->highlight[1] = ev->u.highlight.sy;
            nav->highlight[2] = ev->u.highlight.ex;
            nav->highlight[3] = ev->u.highlight.ey;
            nav->hi_visible = ev->u.highlight.display;
            update_resolution(mpctx);
            osd_set_nav_highlight(mpctx->osd, mpctx);
            break;
        }
        case MP_NAV_EVENT_OVERLAY: {
            osd_set_nav_highlight(mpctx->osd, NULL);
            for (int i = 0; i < 2; i++) {
                if (nav->overlays[i])
                    talloc_free(nav->overlays[i]);
                nav->overlays[i] = talloc_steal(nav, ev->u.overlay.images[i]);
            }
            update_resolution(mpctx);
            osd_set_nav_highlight(mpctx->osd, mpctx);
            break;
        }
        default: ; // ignore
        }
        talloc_free(ev);
    }
    if (mpctx->stop_play == AT_END_OF_FILE) {
        if (nav->nav_still_frame > 0) {
            // gross hack
            mpctx->time_frame += nav->nav_still_frame;
            mpctx->playing_last_frame = true;
            nav->nav_still_frame = -2;
        } else if (nav->nav_still_frame == -2) {
            struct mp_nav_cmd inp = {MP_NAV_CMD_SKIP_STILL};
            stream_control(mpctx->stream, STREAM_CTRL_NAV_CMD, &inp);
        }
    }
    if (nav->nav_draining && mpctx->stop_play == AT_END_OF_FILE) {
        MP_VERBOSE(nav, "execute drain\n");
        struct mp_nav_cmd inp = {MP_NAV_CMD_DRAIN_OK};
        stream_control(mpctx->stream, STREAM_CTRL_NAV_CMD, &inp);
        nav->nav_draining = false;
        stream_control(mpctx->stream, STREAM_CTRL_RESUME_CACHE, NULL);
    }
    // E.g. keep displaying still frames
    if (mpctx->stop_play == AT_END_OF_FILE && !nav->nav_eof)
        mpctx->stop_play = KEEP_PLAYING;
}
Beispiel #6
0
static bool api_EfsRpcDuplicateEncryptionInfoFile(struct pipes_struct *p)
{
	const struct ndr_interface_call *call;
	struct ndr_pull *pull;
	struct ndr_push *push;
	enum ndr_err_code ndr_err;
	struct EfsRpcDuplicateEncryptionInfoFile *r;

	call = &ndr_table_efs.calls[NDR_EFSRPCDUPLICATEENCRYPTIONINFOFILE];

	r = talloc(talloc_tos(), struct EfsRpcDuplicateEncryptionInfoFile);
	if (r == NULL) {
		return false;
	}

	pull = ndr_pull_init_blob(&p->in_data.data, r);
	if (pull == NULL) {
		talloc_free(r);
		return false;
	}

	pull->flags |= LIBNDR_FLAG_REF_ALLOC;
	if (p->endian) {
		pull->flags |= LIBNDR_FLAG_BIGENDIAN;
	}
	ndr_err = call->ndr_pull(pull, NDR_IN, r);
	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
		talloc_free(r);
		return false;
	}

	if (DEBUGLEVEL >= 10) {
		NDR_PRINT_FUNCTION_DEBUG(EfsRpcDuplicateEncryptionInfoFile, NDR_IN, r);
	}

	r->out.result = _EfsRpcDuplicateEncryptionInfoFile(p, r);

	if (p->fault_state) {
		talloc_free(r);
		/* Return true here, srv_pipe_hnd.c will take care */
		return true;
	}

	if (DEBUGLEVEL >= 10) {
		NDR_PRINT_FUNCTION_DEBUG(EfsRpcDuplicateEncryptionInfoFile, NDR_OUT | NDR_SET_VALUES, r);
	}

	push = ndr_push_init_ctx(r);
	if (push == NULL) {
		talloc_free(r);
		return false;
	}

	/*
	 * carry over the pointer count to the reply in case we are
	 * using full pointer. See NDR specification for full pointers
	 */
	push->ptr_count = pull->ptr_count;

	ndr_err = call->ndr_push(push, NDR_OUT, r);
	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
		talloc_free(r);
		return false;
	}

	p->out_data.rdata = ndr_push_blob(push);
	talloc_steal(p->mem_ctx, p->out_data.rdata.data);

	talloc_free(r);

	return true;
}
Beispiel #7
0
static REQUEST *request_setup(FILE *fp)
{
	VALUE_PAIR *vp;
	REQUEST *request;
	vp_cursor_t cursor;

	/*
	 *	Create and initialize the new request.
	 */
	request = request_alloc(NULL);

	request->packet = rad_alloc(request, false);
	if (!request->packet) {
		ERROR("No memory");
		talloc_free(request);
		return NULL;
	}

	request->reply = rad_alloc(request, false);
	if (!request->reply) {
		ERROR("No memory");
		talloc_free(request);
		return NULL;
	}

	request->listener = listen_alloc(request);
	request->client = client_alloc(request);

	request->number = 0;

	request->master_state = REQUEST_ACTIVE;
	request->child_state = REQUEST_RUNNING;
	request->handle = NULL;
	request->server = talloc_typed_strdup(request, "default");

	request->root = &main_config;

	/*
	 *	Read packet from fp
	 */
	if (readvp2(&request->packet->vps, request->packet, fp, &filedone) < 0) {
		fr_perror("unittest");
		talloc_free(request);
		return NULL;
	}

	/*
	 *	Set the defaults for IPs, etc.
	 */
	request->packet->code = PW_CODE_ACCESS_REQUEST;

	request->packet->src_ipaddr.af = AF_INET;
	request->packet->src_ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_LOOPBACK);
	request->packet->src_port = 18120;

	request->packet->dst_ipaddr.af = AF_INET;
	request->packet->dst_ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_LOOPBACK);
	request->packet->dst_port = 1812;

	/*
	 *	Copied from radclient
	 */
#if 1
	/*
	 *	Fix up Digest-Attributes issues
	 */
	for (vp = fr_cursor_init(&cursor, &request->packet->vps);
	     vp;
	     vp = fr_cursor_next(&cursor)) {
		/*
		 *	Double quoted strings get marked up as xlat expansions,
		 *	but we don't support that here.
		 */
		if (vp->type == VT_XLAT) {
			vp->vp_strvalue = vp->value.xlat;
			vp->value.xlat = NULL;
			vp->type = VT_DATA;
		}

		if (!vp->da->vendor) switch (vp->da->attr) {
			default:
				break;

				/*
				 *	Allow it to set the packet type in
				 *	the attributes read from the file.
				 */
			case PW_PACKET_TYPE:
				request->packet->code = vp->vp_integer;
				break;

			case PW_PACKET_DST_PORT:
				request->packet->dst_port = (vp->vp_integer & 0xffff);
				break;

			case PW_PACKET_DST_IP_ADDRESS:
				request->packet->dst_ipaddr.af = AF_INET;
				request->packet->dst_ipaddr.ipaddr.ip4addr.s_addr = vp->vp_ipaddr;
				break;

			case PW_PACKET_DST_IPV6_ADDRESS:
				request->packet->dst_ipaddr.af = AF_INET6;
				request->packet->dst_ipaddr.ipaddr.ip6addr = vp->vp_ipv6addr;
				break;

			case PW_PACKET_SRC_PORT:
				request->packet->src_port = (vp->vp_integer & 0xffff);
				break;

			case PW_PACKET_SRC_IP_ADDRESS:
				request->packet->src_ipaddr.af = AF_INET;
				request->packet->src_ipaddr.ipaddr.ip4addr.s_addr = vp->vp_ipaddr;
				break;

			case PW_PACKET_SRC_IPV6_ADDRESS:
				request->packet->src_ipaddr.af = AF_INET6;
				request->packet->src_ipaddr.ipaddr.ip6addr = vp->vp_ipv6addr;
				break;

			case PW_CHAP_PASSWORD: {
				int i, already_hex = 0;

				/*
				 *	If it's 17 octets, it *might* be already encoded.
				 *	Or, it might just be a 17-character password (maybe UTF-8)
				 *	Check it for non-printable characters.  The odds of ALL
				 *	of the characters being 32..255 is (1-7/8)^17, or (1/8)^17,
				 *	or 1/(2^51), which is pretty much zero.
				 */
				if (vp->length == 17) {
					for (i = 0; i < 17; i++) {
						if (vp->vp_octets[i] < 32) {
							already_hex = 1;
							break;
						}
					}
				}

				/*
				 *	Allow the user to specify ASCII or hex CHAP-Password
				 */
				if (!already_hex) {
					uint8_t *p;
					size_t len, len2;

					len = len2 = vp->length;
					if (len2 < 17) len2 = 17;

					p = talloc_zero_array(vp, uint8_t, len2);

					memcpy(p, vp->vp_strvalue, len);

					rad_chap_encode(request->packet,
							p,
							fr_rand() & 0xff, vp);
					vp->vp_octets = p;
					vp->length = 17;
				}
			}
				break;

			case PW_DIGEST_REALM:
			case PW_DIGEST_NONCE:
			case PW_DIGEST_METHOD:
			case PW_DIGEST_URI:
			case PW_DIGEST_QOP:
			case PW_DIGEST_ALGORITHM:
			case PW_DIGEST_BODY_DIGEST:
			case PW_DIGEST_CNONCE:
			case PW_DIGEST_NONCE_COUNT:
			case PW_DIGEST_USER_NAME:
				/* overlapping! */
			{
				DICT_ATTR const *da;
				uint8_t *p, *q;

				p = talloc_array(vp, uint8_t, vp->length + 2);

				memcpy(p + 2, vp->vp_octets, vp->length);
				p[0] = vp->da->attr - PW_DIGEST_REALM + 1;
				vp->length += 2;
				p[1] = vp->length;

				da = dict_attrbyvalue(PW_DIGEST_ATTRIBUTES, 0);
				rad_assert(da != NULL);
				vp->da = da;

				/*
				 *	Re-do pairmemsteal ourselves,
				 *	because we play games with
				 *	vp->da, and pairmemsteal goes
				 *	to GREAT lengths to sanitize
				 *	and fix and change and
				 *	double-check the various
				 *	fields.
				 */
				memcpy(&q, &vp->vp_octets, sizeof(q));
				talloc_free(q);

				vp->vp_octets = talloc_steal(vp, p);
				vp->type = VT_DATA;

				VERIFY_VP(vp);
			}

			break;
			}
	} /* loop over the VP's we read in */
#endif

	if (debug_flag) {
		for (vp = fr_cursor_init(&cursor, &request->packet->vps);
		     vp;
		     vp = fr_cursor_next(&cursor)) {
			/*
			 *	Take this opportunity to verify all the VALUE_PAIRs are still valid.
			 */
			if (!talloc_get_type(vp, VALUE_PAIR)) {
				ERROR("Expected VALUE_PAIR pointer got \"%s\"", talloc_get_name(vp));

				fr_log_talloc_report(vp);
				rad_assert(0);
			}

			vp_print(fr_log_fp, vp);
		}
		fflush(fr_log_fp);
	}

	/*
	 *	FIXME: set IPs, etc.
	 */
	request->packet->code = PW_CODE_ACCESS_REQUEST;

	request->packet->src_ipaddr.af = AF_INET;
	request->packet->src_ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_LOOPBACK);
	request->packet->src_port = 18120;

	request->packet->dst_ipaddr.af = AF_INET;
	request->packet->dst_ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_LOOPBACK);
	request->packet->dst_port = 1812;

	/*
	 *	Build the reply template from the request.
	 */
	request->reply->sockfd = request->packet->sockfd;
	request->reply->dst_ipaddr = request->packet->src_ipaddr;
	request->reply->src_ipaddr = request->packet->dst_ipaddr;
	request->reply->dst_port = request->packet->src_port;
	request->reply->src_port = request->packet->dst_port;
	request->reply->id = request->packet->id;
	request->reply->code = 0; /* UNKNOWN code */
	memcpy(request->reply->vector, request->packet->vector,
	       sizeof(request->reply->vector));
	request->reply->vps = NULL;
	request->reply->data = NULL;
	request->reply->data_len = 0;

	/*
	 *	Debugging
	 */
	request->log.lvl = debug_flag;
	request->log.func = vradlog_request;

	request->username = pairfind(request->packet->vps, PW_USER_NAME, 0, TAG_ANY);
	request->password = pairfind(request->packet->vps, PW_USER_PASSWORD, 0, TAG_ANY);

	return request;
}
Beispiel #8
0
NTSTATUS libnet_SamSync_netlogon(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, struct libnet_SamSync *r)
{
	NTSTATUS nt_status, dbsync_nt_status;
	TALLOC_CTX *samsync_ctx, *loop_ctx, *delta_ctx;
	struct netlogon_creds_CredentialState *creds;
	struct netr_DatabaseSync dbsync;
	struct netr_Authenticator credential, return_authenticator;
	struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
	struct cli_credentials *machine_account;
	struct dcerpc_pipe *p;
	struct libnet_context *machine_net_ctx;
	struct libnet_RpcConnect *c;
	struct libnet_SamSync_state *state;
	const enum netr_SamDatabaseID database_ids[] = {SAM_DATABASE_DOMAIN, SAM_DATABASE_BUILTIN, SAM_DATABASE_PRIVS}; 
	int i;

	samsync_ctx = talloc_named(mem_ctx, 0, "SamSync top context");

	if (!r->in.machine_account) { 
		machine_account = cli_credentials_init(samsync_ctx);
		if (!machine_account) {
			talloc_free(samsync_ctx);
			return NT_STATUS_NO_MEMORY;
		}
		cli_credentials_set_conf(machine_account, ctx->lp_ctx);
		nt_status = cli_credentials_set_machine_account(machine_account, ctx->lp_ctx);
		if (!NT_STATUS_IS_OK(nt_status)) {
			r->out.error_string = talloc_strdup(mem_ctx, "Could not obtain machine account password - are we joined to the domain?");
			talloc_free(samsync_ctx);
			return nt_status;
		}
	} else {
		machine_account = r->in.machine_account;
	}

	/* We cannot do this unless we are a BDC.  Check, before we get odd errors later */
	if (cli_credentials_get_secure_channel_type(machine_account) != SEC_CHAN_BDC) {
		r->out.error_string
			= talloc_asprintf(mem_ctx, 
					  "Our join to domain %s is not as a BDC (%d), please rejoin as a BDC",
					  cli_credentials_get_domain(machine_account),
					  cli_credentials_get_secure_channel_type(machine_account));
		talloc_free(samsync_ctx);
		return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
	}

	c = talloc(samsync_ctx, struct libnet_RpcConnect);
	if (!c) {
		r->out.error_string = NULL;
		talloc_free(samsync_ctx);
		return NT_STATUS_NO_MEMORY;
	}

	c->level              = LIBNET_RPC_CONNECT_DC_INFO;
	if (r->in.binding_string) {
		c->in.binding = r->in.binding_string;
		c->in.name    = NULL;
	} else {
		c->in.binding = NULL;
		c->in.name    = cli_credentials_get_domain(machine_account);
	}
	
	/* prepare connect to the NETLOGON pipe of PDC */
	c->in.dcerpc_iface      = &ndr_table_netlogon;

	/* We must do this as the machine, not as any command-line
	 * user.  So we override the credentials in the
	 * libnet_context */
	machine_net_ctx = talloc(samsync_ctx, struct libnet_context);
	if (!machine_net_ctx) {
		r->out.error_string = NULL;
		talloc_free(samsync_ctx);
		return NT_STATUS_NO_MEMORY;
	}
	*machine_net_ctx = *ctx;
	machine_net_ctx->cred = machine_account;

	/* connect to the NETLOGON pipe of the PDC */
	nt_status = libnet_RpcConnect(machine_net_ctx, samsync_ctx, c);
	if (!NT_STATUS_IS_OK(nt_status)) {
		if (r->in.binding_string) {
			r->out.error_string = talloc_asprintf(mem_ctx,
							      "Connection to NETLOGON pipe of DC %s failed: %s",
							      r->in.binding_string, c->out.error_string);
		} else {
			r->out.error_string = talloc_asprintf(mem_ctx,
							      "Connection to NETLOGON pipe of DC for %s failed: %s",
							      c->in.name, c->out.error_string);
		}
		talloc_free(samsync_ctx);
		return nt_status;
	}

	/* This makes a new pipe, on which we can do schannel.  We
	 * should do this in the RpcConnect code, but the abstaction
	 * layers do not suit yet */

	nt_status = dcerpc_secondary_connection(c->out.dcerpc_pipe, &p,
						c->out.dcerpc_pipe->binding);

	if (!NT_STATUS_IS_OK(nt_status)) {
		r->out.error_string = talloc_asprintf(mem_ctx,
						      "Secondary connection to NETLOGON pipe of DC %s failed: %s",
						      dcerpc_server_name(p), nt_errstr(nt_status));
		talloc_free(samsync_ctx);
		return nt_status;
	}

	nt_status = dcerpc_bind_auth_schannel(samsync_ctx, p, &ndr_table_netlogon,
					      machine_account, ctx->lp_ctx, DCERPC_AUTH_LEVEL_PRIVACY);

	if (!NT_STATUS_IS_OK(nt_status)) {
		r->out.error_string = talloc_asprintf(mem_ctx,
						      "SCHANNEL authentication to NETLOGON pipe of DC %s failed: %s",
						      dcerpc_server_name(p), nt_errstr(nt_status));
		talloc_free(samsync_ctx);
		return nt_status;
	}

	state = talloc(samsync_ctx, struct libnet_SamSync_state);
	if (!state) {
		r->out.error_string = NULL;
		talloc_free(samsync_ctx);
		return nt_status;
	}		

	state->domain_name     = c->out.domain_name;
	state->domain_sid      = c->out.domain_sid;
	state->realm           = c->out.realm;
	state->domain_guid     = c->out.guid;
	state->machine_net_ctx = machine_net_ctx;
	state->netlogon_pipe   = p;

	/* initialise the callback layer.  It may wish to contact the
	 * server with ldap, now we know the name */
	
	if (r->in.init_fn) {
		char *error_string;
		nt_status = r->in.init_fn(samsync_ctx, 
					  r->in.fn_ctx,
					  state, 
					  &error_string); 
		if (!NT_STATUS_IS_OK(nt_status)) {
			r->out.error_string = talloc_steal(mem_ctx, error_string);
			talloc_free(samsync_ctx);
			return nt_status;
		}
	}

	/* get NETLOGON credentials */

	nt_status = dcerpc_schannel_creds(p->conn->security_state.generic_state, samsync_ctx, &creds);
	if (!NT_STATUS_IS_OK(nt_status)) {
		r->out.error_string = talloc_strdup(mem_ctx, "Could not obtain NETLOGON credentials from DCERPC/GENSEC layer");
		talloc_free(samsync_ctx);
		return nt_status;
	}

	/* Setup details for the synchronisation */

	ZERO_STRUCT(return_authenticator);

	dbsync.in.logon_server = talloc_asprintf(samsync_ctx, "\\\\%s", dcerpc_server_name(p));
	dbsync.in.computername = cli_credentials_get_workstation(machine_account);
	dbsync.in.preferredmaximumlength = (uint32_t)-1;
	dbsync.in.return_authenticator = &return_authenticator;
	dbsync.out.return_authenticator = &return_authenticator;
	dbsync.out.delta_enum_array = &delta_enum_array;

	for (i=0;i< ARRAY_SIZE(database_ids); i++) {

		uint32_t sync_context = 0;

		dbsync.in.database_id = database_ids[i];
		dbsync.in.sync_context = &sync_context;
		dbsync.out.sync_context = &sync_context;
		
		do {
			int d;
			loop_ctx = talloc_named(samsync_ctx, 0, "DatabaseSync loop context");
			netlogon_creds_client_authenticator(creds, &credential);

			dbsync.in.credential = &credential;
			
			dbsync_nt_status = dcerpc_netr_DatabaseSync(p, loop_ctx, &dbsync);
			if (!NT_STATUS_IS_OK(dbsync_nt_status) &&
			    !NT_STATUS_EQUAL(dbsync_nt_status, STATUS_MORE_ENTRIES)) {
				r->out.error_string = talloc_asprintf(mem_ctx, "DatabaseSync failed - %s", nt_errstr(nt_status));
				talloc_free(samsync_ctx);
				return nt_status;
			}
			
			if (!netlogon_creds_client_check(creds, &dbsync.out.return_authenticator->cred)) {
				r->out.error_string = talloc_strdup(mem_ctx, "Credential chaining on incoming DatabaseSync failed");
				talloc_free(samsync_ctx);
				return NT_STATUS_ACCESS_DENIED;
			}
			
			dbsync.in.sync_context = dbsync.out.sync_context;
			
			/* For every single remote 'delta' entry: */
			for (d=0; d < delta_enum_array->num_deltas; d++) {
				char *error_string = NULL;
				delta_ctx = talloc_named(loop_ctx, 0, "DatabaseSync delta context");
				/* 'Fix' elements, by decrypting and
				 * de-obfuscating the data */
				nt_status = samsync_fix_delta(delta_ctx, 
							      creds, 
							      dbsync.in.database_id,
							      &delta_enum_array->delta_enum[d]);
				if (!NT_STATUS_IS_OK(nt_status)) {
					r->out.error_string = talloc_steal(mem_ctx, error_string);
					talloc_free(samsync_ctx);
					return nt_status;
				}

				/* Now call the callback.  This will
				 * do something like print the data or
				 * write to an ldb */
				nt_status = r->in.delta_fn(delta_ctx, 
							   r->in.fn_ctx,
							   dbsync.in.database_id,
							   &delta_enum_array->delta_enum[d],
							   &error_string);
				if (!NT_STATUS_IS_OK(nt_status)) {
					r->out.error_string = talloc_steal(mem_ctx, error_string);
					talloc_free(samsync_ctx);
					return nt_status;
				}
				talloc_free(delta_ctx);
			}
			talloc_free(loop_ctx);
		} while (NT_STATUS_EQUAL(dbsync_nt_status, STATUS_MORE_ENTRIES));
		
		if (!NT_STATUS_IS_OK(dbsync_nt_status)) {
			r->out.error_string = talloc_asprintf(mem_ctx, "libnet_SamSync_netlogon failed: unexpected inconsistancy. Should not get error %s here", nt_errstr(nt_status));
			talloc_free(samsync_ctx);
			return dbsync_nt_status;
		}
		nt_status = NT_STATUS_OK;
	}
	talloc_free(samsync_ctx);
	return nt_status;
}
Beispiel #9
0
/*
  create a RID Set object for the specified DC
 */
static int ridalloc_create_rid_set_ntds(struct ldb_module *module, TALLOC_CTX *mem_ctx,
					struct ldb_dn *rid_manager_dn,
					struct ldb_dn *ntds_dn, struct ldb_dn **dn)
{
	TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
	struct ldb_dn *server_dn, *machine_dn, *rid_set_dn;
	int ret;
	uint64_t dc_pool;
	struct ldb_message *msg;
	struct ldb_context *ldb = ldb_module_get_ctx(module);

	/*
	  steps:

	  find the machine object for the DC
	  construct the RID Set DN
	  load rIDAvailablePool to find next available set
	  modify RID Manager object to update rIDAvailablePool
	  add the RID Set object
	  link to the RID Set object in machine object
	 */

	server_dn = ldb_dn_get_parent(tmp_ctx, ntds_dn);
	if (!server_dn) {
		ldb_module_oom(module);
		talloc_free(tmp_ctx);
		return LDB_ERR_OPERATIONS_ERROR;
	}

	ret = dsdb_module_reference_dn(module, tmp_ctx, server_dn, "serverReference", &machine_dn);
	if (ret != LDB_SUCCESS) {
		ldb_asprintf_errstring(ldb, "Failed to find serverReference in %s - %s",
				       ldb_dn_get_linearized(server_dn), ldb_errstring(ldb));
		talloc_free(tmp_ctx);
		return ret;
	}

	rid_set_dn = ldb_dn_copy(tmp_ctx, machine_dn);
	if (rid_set_dn == NULL) {
		ldb_module_oom(module);
		return LDB_ERR_OPERATIONS_ERROR;
	}

	if (! ldb_dn_add_child_fmt(rid_set_dn, "CN=RID Set")) {
		ldb_module_oom(module);
		return LDB_ERR_OPERATIONS_ERROR;
	}

	/* grab a pool from the RID Manager object */
	ret = ridalloc_rid_manager_allocate(module, rid_manager_dn, &dc_pool);
	if (ret != LDB_SUCCESS) {
		talloc_free(tmp_ctx);
		return ret;
	}

	/* create the RID Set object */
	msg = ldb_msg_new(tmp_ctx);
	msg->dn = rid_set_dn;

	ret = ldb_msg_add_string(msg, "objectClass", "rIDSet");
	if (ret != LDB_SUCCESS) {
		talloc_free(tmp_ctx);
		return ret;
	}
	ret = ldb_msg_add_fmt(msg, "rIDAllocationPool", "%llu", (unsigned long long)dc_pool);
	if (ret != LDB_SUCCESS) {
		talloc_free(tmp_ctx);
		return ret;
	}

	/* w2k8-r2 sets these to zero when first created */
	ret = ldb_msg_add_fmt(msg, "rIDPreviousAllocationPool", "0");
	if (ret != LDB_SUCCESS) {
		talloc_free(tmp_ctx);
		return ret;
	}
	ret = ldb_msg_add_fmt(msg, "rIDUsedPool", "0");
	if (ret != LDB_SUCCESS) {
		talloc_free(tmp_ctx);
		return ret;
	}
	ret = ldb_msg_add_fmt(msg, "rIDNextRID", "0");
	if (ret != LDB_SUCCESS) {
		talloc_free(tmp_ctx);
		return ret;
	}

	/* we need this to go all the way to the top of the module
	 * stack, as we need all the extra attributes added (including
	 * complex ones like ntsecuritydescriptor) */
	ret = dsdb_module_add(module, msg, DSDB_FLAG_TOP_MODULE | DSDB_MODIFY_RELAX);
	if (ret != LDB_SUCCESS) {
		ldb_asprintf_errstring(ldb, "Failed to add RID Set %s - %s",
				       ldb_dn_get_linearized(msg->dn),
				       ldb_errstring(ldb));
		talloc_free(tmp_ctx);
		return ret;
	}

	/* add the rIDSetReferences link */
	msg = ldb_msg_new(tmp_ctx);
	msg->dn = machine_dn;

	ret = ldb_msg_add_string(msg, "rIDSetReferences", ldb_dn_get_linearized(rid_set_dn));
	if (ret != LDB_SUCCESS) {
		talloc_free(tmp_ctx);
		return ret;
	}
	msg->elements[0].flags = LDB_FLAG_MOD_ADD;

	ret = dsdb_module_modify(module, msg, 0);
	if (ret != LDB_SUCCESS) {
		ldb_asprintf_errstring(ldb, "Failed to add rIDSetReferences to %s - %s",
				       ldb_dn_get_linearized(msg->dn),
				       ldb_errstring(ldb));
		talloc_free(tmp_ctx);
		return ret;
	}

	(*dn) = talloc_steal(mem_ctx, rid_set_dn);

	talloc_free(tmp_ctx);
	return LDB_SUCCESS;
}
Beispiel #10
0
/*
  return sequenceNumber from @BASEINFO
*/
static int ltdb_sequence_number(struct ltdb_context *ctx,
				struct ldb_extended **ext)
{
	struct ldb_context *ldb;
	struct ldb_module *module = ctx->module;
	struct ldb_request *req = ctx->req;
	TALLOC_CTX *tmp_ctx;
	struct ldb_seqnum_request *seq;
	struct ldb_seqnum_result *res;
	struct ldb_message *msg = NULL;
	struct ldb_dn *dn;
	const char *date;
	int ret = LDB_SUCCESS;

	ldb = ldb_module_get_ctx(module);

	seq = talloc_get_type(req->op.extended.data,
				struct ldb_seqnum_request);
	if (seq == NULL) {
		return LDB_ERR_OPERATIONS_ERROR;
	}

	ldb_request_set_state(req, LDB_ASYNC_PENDING);

	if (ltdb_lock_read(module) != 0) {
		return LDB_ERR_OPERATIONS_ERROR;
	}

	res = talloc_zero(req, struct ldb_seqnum_result);
	if (res == NULL) {
		ret = LDB_ERR_OPERATIONS_ERROR;
		goto done;
	}
	tmp_ctx = talloc_new(req);
	if (tmp_ctx == NULL) {
		ret = LDB_ERR_OPERATIONS_ERROR;
		goto done;
	}

	dn = ldb_dn_new(tmp_ctx, ldb, LTDB_BASEINFO);

	msg = talloc(tmp_ctx, struct ldb_message);
	if (msg == NULL) {
		ret = LDB_ERR_OPERATIONS_ERROR;
		goto done;
	}

	ret = ltdb_search_dn1(module, dn, msg);
	if (ret != LDB_SUCCESS) {
		goto done;
	}

	switch (seq->type) {
	case LDB_SEQ_HIGHEST_SEQ:
		res->seq_num = ldb_msg_find_attr_as_uint64(msg, LTDB_SEQUENCE_NUMBER, 0);
		break;
	case LDB_SEQ_NEXT:
		res->seq_num = ldb_msg_find_attr_as_uint64(msg, LTDB_SEQUENCE_NUMBER, 0);
		res->seq_num++;
		break;
	case LDB_SEQ_HIGHEST_TIMESTAMP:
		date = ldb_msg_find_attr_as_string(msg, LTDB_MOD_TIMESTAMP, NULL);
		if (date) {
			res->seq_num = ldb_string_to_time(date);
		} else {
			res->seq_num = 0;
			/* zero is as good as anything when we don't know */
		}
		break;
	}

	*ext = talloc_zero(req, struct ldb_extended);
	if (*ext == NULL) {
		ret = LDB_ERR_OPERATIONS_ERROR;
		goto done;
	}
	(*ext)->oid = LDB_EXTENDED_SEQUENCE_NUMBER;
	(*ext)->data = talloc_steal(*ext, res);

done:
	talloc_free(tmp_ctx);
	ltdb_unlock_read(module);
	return ret;
}
Beispiel #11
0
/*
  connect to the database
*/
static int ltdb_connect(struct ldb_context *ldb, const char *url,
			unsigned int flags, const char *options[],
			struct ldb_module **_module)
{
	struct ldb_module *module;
	const char *path;
	int tdb_flags, open_flags;
	struct ltdb_private *ltdb;

	/* parse the url */
	if (strchr(url, ':')) {
		if (strncmp(url, "tdb://", 6) != 0) {
			ldb_debug(ldb, LDB_DEBUG_ERROR,
				  "Invalid tdb URL '%s'", url);
			return LDB_ERR_OPERATIONS_ERROR;
		}
		path = url+6;
	} else {
		path = url;
	}

	tdb_flags = TDB_DEFAULT | TDB_SEQNUM;

	/* check for the 'nosync' option */
	if (flags & LDB_FLG_NOSYNC) {
		tdb_flags |= TDB_NOSYNC;
	}

	/* and nommap option */
	if (flags & LDB_FLG_NOMMAP) {
		tdb_flags |= TDB_NOMMAP;
	}

	if (flags & LDB_FLG_RDONLY) {
		open_flags = O_RDONLY;
	} else {
		open_flags = O_CREAT | O_RDWR;
	}

	ltdb = talloc_zero(ldb, struct ltdb_private);
	if (!ltdb) {
		ldb_oom(ldb);
		return LDB_ERR_OPERATIONS_ERROR;
	}

	/* note that we use quite a large default hash size */
	ltdb->tdb = ltdb_wrap_open(ltdb, path, 10000,
				   tdb_flags, open_flags,
				   ldb_get_create_perms(ldb), ldb);
	if (!ltdb->tdb) {
		ldb_debug(ldb, LDB_DEBUG_ERROR,
			  "Unable to open tdb '%s'", path);
		talloc_free(ltdb);
		return LDB_ERR_OPERATIONS_ERROR;
	}

	ltdb->sequence_number = 0;

	module = ldb_module_new(ldb, ldb, "ldb_tdb backend", &ltdb_ops);
	if (!module) {
		talloc_free(ltdb);
		return LDB_ERR_OPERATIONS_ERROR;
	}
	ldb_module_set_private(module, ltdb);
	talloc_steal(module, ltdb);

	if (ltdb_cache_load(module) != 0) {
		talloc_free(module);
		talloc_free(ltdb);
		return LDB_ERR_OPERATIONS_ERROR;
	}

	*_module = module;
	return LDB_SUCCESS;
}
Beispiel #12
0
#include <talloc.h>

#include "lisp_value.h"
#include "metadata.h"

void lisp_value_set_meta(lisp_value *this, metadata *meta)
{
    this->meta = talloc_steal(this, meta);
}
Beispiel #13
0
/*
  load the current ACL from system.nfs4acl
*/
static NTSTATUS pvfs_acl_load_nfs4(struct pvfs_state *pvfs, struct pvfs_filename *name, int fd,
				   TALLOC_CTX *mem_ctx,
				   struct security_descriptor **psd)
{
	NTSTATUS status;
	struct nfs4acl *acl;
	struct security_descriptor *sd;
	int i, num_ids;
	struct id_map *ids;

	acl = talloc_zero(mem_ctx, struct nfs4acl);
	NT_STATUS_HAVE_NO_MEMORY(acl);

	status = pvfs_xattr_ndr_load(pvfs, mem_ctx, name->full_name, fd, 
				     NFS4ACL_XATTR_NAME,
				     acl, (void *) ndr_pull_nfs4acl);
	if (!NT_STATUS_IS_OK(status)) {
		talloc_free(acl);
		return status;
	}

	*psd = security_descriptor_initialise(mem_ctx);
	NT_STATUS_HAVE_NO_MEMORY(*psd);

	sd = *psd;

	sd->type |= acl->a_flags;

	/* the number of ids to map is the acl count plus uid and gid */
	num_ids = acl->a_count +2;
	ids = talloc_array(sd, struct id_map, num_ids);
	NT_STATUS_HAVE_NO_MEMORY(ids);

	ids[0].xid.id = name->st.st_uid;
	ids[0].xid.type = ID_TYPE_UID;
	ids[0].sid = NULL;
	ids[0].status = ID_UNKNOWN;

	ids[1].xid.id = name->st.st_gid;
	ids[1].xid.type = ID_TYPE_GID;
	ids[1].sid = NULL;
	ids[1].status = ID_UNKNOWN;

	for (i=0;i<acl->a_count;i++) {
		struct nfs4ace *a = &acl->ace[i];
		ids[i+2].xid.id = a->e_id;
		if (a->e_flags & ACE4_IDENTIFIER_GROUP) {
			ids[i+2].xid.type = ID_TYPE_GID;
		} else {
			ids[i+2].xid.type = ID_TYPE_UID;
		}
		ids[i+2].sid = NULL;
		ids[i+2].status = ID_UNKNOWN;
	}

	/* Allocate memory for the sids from the security descriptor to be on
	 * the safe side. */
	status = wbc_xids_to_sids(pvfs->ntvfs->ctx->event_ctx, ids, num_ids);
	NT_STATUS_NOT_OK_RETURN(status);

	sd->owner_sid = talloc_steal(sd, ids[0].sid);
	sd->group_sid = talloc_steal(sd, ids[1].sid);

	for (i=0;i<acl->a_count;i++) {
		struct nfs4ace *a = &acl->ace[i];
		struct security_ace ace;
		ace.type = a->e_type;
		ace.flags = a->e_flags;
		ace.access_mask = a->e_mask;
		ace.trustee = *ids[i+2].sid;
		security_descriptor_dacl_add(sd, &ace);
	}

	return NT_STATUS_OK;
}
Beispiel #14
0
/* Get the keytab (actually, a container containing the krb5_keytab)
 * attached to this context.  If this hasn't been done or set before,
 * it will be generated from the password.
 */
_PUBLIC_ int cli_credentials_get_keytab(struct cli_credentials *cred, 
					struct loadparm_context *lp_ctx,
					struct keytab_container **_ktc)
{
	krb5_error_code ret;
	struct keytab_container *ktc;
	struct smb_krb5_context *smb_krb5_context;
	const char *keytab_name;
	krb5_keytab keytab;
	TALLOC_CTX *mem_ctx;
	const char *username = cli_credentials_get_username(cred);
	const char *realm = cli_credentials_get_realm(cred);
	const char *error_string;
	const char *salt_principal;

	if (cred->keytab_obtained >= (MAX(cred->principal_obtained, 
					  cred->username_obtained))) {
		*_ktc = cred->keytab;
		return 0;
	}

	if (cli_credentials_is_anonymous(cred)) {
		return EINVAL;
	}

	ret = cli_credentials_get_krb5_context(cred, lp_ctx,
					       &smb_krb5_context);
	if (ret) {
		return ret;
	}

	mem_ctx = talloc_new(cred);
	if (!mem_ctx) {
		return ENOMEM;
	}

	/*
	 * FIXME: Currently there is no better way than to create the correct
	 * salt principal by checking if the username ends with a '$'. It would
	 * be better if it is part of the credentials.
	 */
	ret = smb_krb5_create_salt_principal(mem_ctx,
					     username,
					     realm,
					     &salt_principal,
					     &error_string);
	if (ret) {
		talloc_free(mem_ctx);
		return ret;
	}

	ret = smb_krb5_create_memory_keytab(mem_ctx,
					    smb_krb5_context->krb5_context,
					    cli_credentials_get_password(cred),
					    username,
					    realm,
					    salt_principal,
					    cli_credentials_get_kvno(cred),
					    &keytab,
					    &keytab_name);
	if (ret) {
		talloc_free(mem_ctx);
		return ret;
	}

	ret = smb_krb5_get_keytab_container(mem_ctx, smb_krb5_context,
					    keytab, keytab_name, &ktc);
	if (ret) {
		talloc_free(mem_ctx);
		return ret;
	}

	cred->keytab_obtained = (MAX(cred->principal_obtained, 
				     cred->username_obtained));

	/* We make this keytab up based on a password.  Therefore
	 * match-by-key is acceptable, we can't match on the wrong
	 * principal */
	ktc->password_based = true;

	talloc_steal(cred, ktc);
	cred->keytab = ktc;
	*_ktc = cred->keytab;
	talloc_free(mem_ctx);
	return ret;
}
Beispiel #15
0
/*
  handler for old style session setup
*/
static void sesssetup_old(struct smbsrv_request *req, union smb_sesssetup *sess)
{
    struct auth_usersupplied_info *user_info = NULL;
    struct tsocket_address *remote_address;
    const char *remote_machine = NULL;
    struct tevent_req *subreq;
    struct sesssetup_context *state;

    sess->old.out.vuid = 0;
    sess->old.out.action = 0;

    sesssetup_common_strings(req,
                             &sess->old.out.os,
                             &sess->old.out.lanman,
                             &sess->old.out.domain);

    if (!req->smb_conn->negotiate.done_sesssetup) {
        req->smb_conn->negotiate.max_send = sess->old.in.bufsize;
    }

    if (req->smb_conn->negotiate.calling_name) {
        remote_machine = req->smb_conn->negotiate.calling_name->name;
    }

    remote_address = socket_get_remote_addr(req->smb_conn->connection->socket, req);
    if (!remote_address) goto nomem;

    if (!remote_machine) {
        remote_machine = tsocket_address_inet_addr_string(remote_address, req);
        if (!remote_machine) goto nomem;
    }

    user_info = talloc_zero(req, struct auth_usersupplied_info);
    if (!user_info) goto nomem;

    user_info->mapped_state = false;
    user_info->logon_parameters = 0;
    user_info->flags = 0;
    user_info->client.account_name = sess->old.in.user;
    user_info->client.domain_name = sess->old.in.domain;
    user_info->workstation_name = remote_machine;
    user_info->remote_host = talloc_steal(user_info, remote_address);

    user_info->password_state = AUTH_PASSWORD_RESPONSE;
    user_info->password.response.lanman = sess->old.in.password;
    user_info->password.response.lanman.data = talloc_steal(user_info, sess->old.in.password.data);
    user_info->password.response.nt = data_blob(NULL, 0);

    state = talloc(req, struct sesssetup_context);
    if (!state) goto nomem;

    if (req->smb_conn->negotiate.auth_context) {
        state->auth_context = req->smb_conn->negotiate.auth_context;
    } else {
        /* TODO: should we use just "anonymous" here? */
        NTSTATUS status = auth_context_create(state,
                                              req->smb_conn->connection->event.ctx,
                                              req->smb_conn->connection->msg_ctx,
                                              req->smb_conn->lp_ctx,
                                              &state->auth_context);
        if (!NT_STATUS_IS_OK(status)) {
            smbsrv_sesssetup_backend_send(req, sess, status);
            return;
        }
    }

    state->req = req;

    subreq = auth_check_password_send(state,
                                      req->smb_conn->connection->event.ctx,
                                      req->smb_conn->negotiate.auth_context,
                                      user_info);
    if (!subreq) goto nomem;
    tevent_req_set_callback(subreq, sesssetup_old_send, state);
    return;

nomem:
    smbsrv_sesssetup_backend_send(req, sess, NT_STATUS_NO_MEMORY);
}
Beispiel #16
0
static NTSTATUS create_conn_struct_as_root(TALLOC_CTX *ctx,
			    struct tevent_context *ev,
			    struct messaging_context *msg,
			    connection_struct **pconn,
			    int snum,
			    const char *path,
			    const struct auth_session_info *session_info)
{
	connection_struct *conn;
	char *connpath;
	const char *vfs_user;
	struct smbd_server_connection *sconn;
	const char *servicename = lp_const_servicename(snum);

	sconn = talloc_zero(ctx, struct smbd_server_connection);
	if (sconn == NULL) {
		return NT_STATUS_NO_MEMORY;
	}

	sconn->ev_ctx = ev;
	sconn->msg_ctx = msg;
	sconn->sock = -1;
	sconn->smb1.echo_handler.trusted_fd = -1;
	sconn->smb1.echo_handler.socket_lock_fd = -1;

	conn = conn_new(sconn);
	if (conn == NULL) {
		TALLOC_FREE(sconn);
		return NT_STATUS_NO_MEMORY;
	}

	/* Now we have conn, we need to make sconn a child of conn,
	 * for a proper talloc tree */
	talloc_steal(conn, sconn);

	if (snum == -1 && servicename == NULL) {
		servicename = "Unknown Service (snum == -1)";
	}

	connpath = talloc_strdup(conn, path);
	if (!connpath) {
		TALLOC_FREE(conn);
		return NT_STATUS_NO_MEMORY;
	}
	connpath = talloc_string_sub(conn,
				     connpath,
				     "%S",
				     servicename);
	if (!connpath) {
		TALLOC_FREE(conn);
		return NT_STATUS_NO_MEMORY;
	}

	/* needed for smbd_vfs_init() */

	conn->params->service = snum;
	conn->cnum = TID_FIELD_INVALID;

	if (session_info != NULL) {
		conn->session_info = copy_session_info(conn, session_info);
		if (conn->session_info == NULL) {
			DEBUG(0, ("copy_serverinfo failed\n"));
			TALLOC_FREE(conn);
			return NT_STATUS_NO_MEMORY;
		}
		vfs_user = conn->session_info->unix_info->unix_name;
	} else {
		/* use current authenticated user in absence of session_info */
		vfs_user = get_current_username();
	}

	set_conn_connectpath(conn, connpath);

	/*
	 * New code to check if there's a share security descripter
	 * added from NT server manager. This is done after the
	 * smb.conf checks are done as we need a uid and token. JRA.
	 *
	 */
	if (conn->session_info) {
		share_access_check(conn->session_info->security_token,
				   servicename,
				   MAXIMUM_ALLOWED_ACCESS,
				   &conn->share_access);

		if ((conn->share_access & FILE_WRITE_DATA) == 0) {
			if ((conn->share_access & FILE_READ_DATA) == 0) {
				/* No access, read or write. */
				DEBUG(0,("create_conn_struct: connection to %s "
					 "denied due to security "
					 "descriptor.\n",
					 servicename));
				conn_free(conn);
				return NT_STATUS_ACCESS_DENIED;
			} else {
				conn->read_only = true;
			}
		}
	} else {
		conn->share_access = 0;
		conn->read_only = true;
	}

	if (!smbd_vfs_init(conn)) {
		NTSTATUS status = map_nt_error_from_unix(errno);
		DEBUG(0,("create_conn_struct: smbd_vfs_init failed.\n"));
		conn_free(conn);
		return status;
	}

	/* this must be the first filesystem operation that we do */
	if (SMB_VFS_CONNECT(conn, servicename, vfs_user) < 0) {
		DEBUG(0,("VFS connect failed!\n"));
		conn_free(conn);
		return NT_STATUS_UNSUCCESSFUL;
	}

	conn->fs_capabilities = SMB_VFS_FS_CAPABILITIES(conn, &conn->ts_res);
	*pconn = conn;

	return NT_STATUS_OK;
}
Beispiel #17
0
/*
  handler for NT1 style session setup
*/
static void sesssetup_nt1(struct smbsrv_request *req, union smb_sesssetup *sess)
{
    NTSTATUS status;
    struct auth_usersupplied_info *user_info = NULL;
    struct tsocket_address *remote_address;
    const char *remote_machine = NULL;
    struct tevent_req *subreq;
    struct sesssetup_context *state;

    sess->nt1.out.vuid = 0;
    sess->nt1.out.action = 0;

    sesssetup_common_strings(req,
                             &sess->nt1.out.os,
                             &sess->nt1.out.lanman,
                             &sess->nt1.out.domain);

    if (!req->smb_conn->negotiate.done_sesssetup) {
        req->smb_conn->negotiate.max_send = sess->nt1.in.bufsize;
        req->smb_conn->negotiate.client_caps = sess->nt1.in.capabilities;
    }

    state = talloc(req, struct sesssetup_context);
    if (!state) goto nomem;

    state->req = req;

    if (req->smb_conn->negotiate.oid) {
        if (sess->nt1.in.user && *sess->nt1.in.user) {
            /* We can't accept a normal login, because we
             * don't have a challenge */
            status = NT_STATUS_LOGON_FAILURE;
            goto failed;
        }

        /* TODO: should we use just "anonymous" here? */
        status = auth_context_create(state,
                                     req->smb_conn->connection->event.ctx,
                                     req->smb_conn->connection->msg_ctx,
                                     req->smb_conn->lp_ctx,
                                     &state->auth_context);
        if (!NT_STATUS_IS_OK(status)) goto failed;
    } else if (req->smb_conn->negotiate.auth_context) {
        state->auth_context = req->smb_conn->negotiate.auth_context;
    } else {
        /* TODO: should we use just "anonymous" here? */
        status = auth_context_create(state,
                                     req->smb_conn->connection->event.ctx,
                                     req->smb_conn->connection->msg_ctx,
                                     req->smb_conn->lp_ctx,
                                     &state->auth_context);
        if (!NT_STATUS_IS_OK(status)) goto failed;
    }

    if (req->smb_conn->negotiate.calling_name) {
        remote_machine = req->smb_conn->negotiate.calling_name->name;
    }

    remote_address = socket_get_remote_addr(req->smb_conn->connection->socket, req);
    if (!remote_address) goto nomem;

    if (!remote_machine) {
        remote_machine = tsocket_address_inet_addr_string(remote_address, req);
        if (!remote_machine) goto nomem;
    }

    user_info = talloc_zero(req, struct auth_usersupplied_info);
    if (!user_info) goto nomem;

    user_info->mapped_state = false;
    user_info->logon_parameters = 0;
    user_info->flags = 0;
    user_info->client.account_name = sess->nt1.in.user;
    user_info->client.domain_name = sess->nt1.in.domain;
    user_info->workstation_name = remote_machine;
    user_info->remote_host = talloc_steal(user_info, remote_address);

    user_info->password_state = AUTH_PASSWORD_RESPONSE;
    user_info->password.response.lanman = sess->nt1.in.password1;
    user_info->password.response.lanman.data = talloc_steal(user_info, sess->nt1.in.password1.data);
    user_info->password.response.nt = sess->nt1.in.password2;
    user_info->password.response.nt.data = talloc_steal(user_info, sess->nt1.in.password2.data);

    subreq = auth_check_password_send(state,
                                      req->smb_conn->connection->event.ctx,
                                      state->auth_context,
                                      user_info);
    if (!subreq) goto nomem;
    tevent_req_set_callback(subreq, sesssetup_nt1_send, state);

    return;

nomem:
    status = NT_STATUS_NO_MEMORY;
failed:
    status = nt_status_squash(status);
    smbsrv_sesssetup_backend_send(req, sess, status);
}
Beispiel #18
0
/*
  load the partitions list based on replicated NC attributes in our
  NTDSDSA object
 */
WERROR dreplsrv_load_partitions(struct dreplsrv_service *s)
{
	WERROR status;
	static const char *attrs[] = { "hasMasterNCs", "msDS-hasMasterNCs", "hasPartialReplicaNCs", "msDS-HasFullReplicaNCs", NULL };
	unsigned int a;
	int ret;
	TALLOC_CTX *tmp_ctx;
	struct ldb_result *res;
	struct ldb_message_element *el;
	struct ldb_dn *ntds_dn;

	tmp_ctx = talloc_new(s);
	W_ERROR_HAVE_NO_MEMORY(tmp_ctx);

	ntds_dn = samdb_ntds_settings_dn(s->samdb);
	if (!ntds_dn) {
		DEBUG(1,(__location__ ": Unable to find ntds_dn: %s\n", ldb_errstring(s->samdb)));
		talloc_free(tmp_ctx);
		return WERR_DS_DRA_INTERNAL_ERROR;
	}

	ret = dsdb_search_dn(s->samdb, tmp_ctx, &res, ntds_dn, attrs, DSDB_SEARCH_SHOW_EXTENDED_DN);
	if (ret != LDB_SUCCESS) {
		DEBUG(1,("Searching for hasMasterNCs in NTDS DN failed: %s\n", ldb_errstring(s->samdb)));
		talloc_free(tmp_ctx);
		return WERR_DS_DRA_INTERNAL_ERROR;
	}

	for (a=0; attrs[a]; a++) {
		int i;

		el = ldb_msg_find_element(res->msgs[0], attrs[a]);
		if (el == NULL) {
			continue;
		}
		for (i=0; i<el->num_values; i++) {
			struct ldb_dn *pdn;
			struct dreplsrv_partition *p, *tp;
			bool found;

			pdn = ldb_dn_from_ldb_val(tmp_ctx, s->samdb, &el->values[i]);
			if (pdn == NULL) {
				talloc_free(tmp_ctx);
				return WERR_DS_DRA_INTERNAL_ERROR;
			}
			if (!ldb_dn_validate(pdn)) {
				return WERR_DS_DRA_INTERNAL_ERROR;
			}

			p = talloc_zero(s, struct dreplsrv_partition);
			W_ERROR_HAVE_NO_MEMORY(p);

			p->dn = talloc_steal(p, pdn);
			p->service = s;

			if (strcasecmp(attrs[a], "hasPartialReplicaNCs") == 0) {
				p->partial_replica = true;
			} else if (strcasecmp(attrs[a], "msDS-HasFullReplicaNCs") == 0) {
				p->rodc_replica = true;
			}

			/* Do not add partitions more than once */
			found = false;
			for (tp = s->partitions; tp; tp = tp->next) {
				if (ldb_dn_compare(tp->dn, p->dn) == 0) {
					found = true;
					break;
				}
			}
			if (found) {
				talloc_free(p);
				continue;
			}

			DLIST_ADD(s->partitions, p);
			DEBUG(2, ("dreplsrv_partition[%s] loaded\n", ldb_dn_get_linearized(p->dn)));
		}
	}

	talloc_free(tmp_ctx);

	status = dreplsrv_refresh_partitions(s);
	W_ERROR_NOT_OK_RETURN(status);

	return WERR_OK;
}
Beispiel #19
0
/* Store the DN of a single search result in context. */
static int map_search_self_callback(struct ldb_request *req, struct ldb_reply *ares)
{
	struct ldb_context *ldb;
	struct map_context *ac;
	int ret;

	ac = talloc_get_type(req->context, struct map_context);
	ldb = ldb_module_get_ctx(ac->module);

	if (!ares) {
		return ldb_module_done(ac->req, NULL, NULL,
					LDB_ERR_OPERATIONS_ERROR);
	}
	if (ares->error != LDB_SUCCESS) {
		return ldb_module_done(ac->req, ares->controls,
					ares->response, ares->error);
	}

	/* We are interested only in the single reply */
	switch(ares->type) {
	case LDB_REPLY_ENTRY:
		/* We have already found a remote DN */
		if (ac->local_dn) {
			ldb_set_errstring(ldb,
					  "Too many results!");
			return ldb_module_done(ac->req, NULL, NULL,
						LDB_ERR_OPERATIONS_ERROR);
		}

		/* Store local DN */
		ac->local_dn = talloc_steal(ac, ares->message->dn);
		break;

	case LDB_REPLY_DONE:

		switch (ac->req->operation) {
		case LDB_MODIFY:
			ret = map_modify_do_local(ac);
			break;
		case LDB_DELETE:
			ret = map_delete_do_local(ac);
			break;
		case LDB_RENAME:
			ret = map_rename_do_local(ac);
			break;
		default:
			/* if we get here we have definitely a problem */
			ret = LDB_ERR_OPERATIONS_ERROR;
		}
		if (ret != LDB_SUCCESS) {
			return ldb_module_done(ac->req, NULL, NULL,
						LDB_ERR_OPERATIONS_ERROR);
		}

	default:
		/* ignore referrals */
		break;
	}

	talloc_free(ares);
	return LDB_SUCCESS;
}
Beispiel #20
0
static bool api_BrowserrServerEnum(struct pipes_struct *p)
{
	const struct ndr_interface_call *call;
	struct ndr_pull *pull;
	struct ndr_push *push;
	enum ndr_err_code ndr_err;
	struct BrowserrServerEnum *r;

	call = &ndr_table_browser.calls[NDR_BROWSERRSERVERENUM];

	r = talloc(talloc_tos(), struct BrowserrServerEnum);
	if (r == NULL) {
		return false;
	}

	pull = ndr_pull_init_blob(&p->in_data.data, r);
	if (pull == NULL) {
		talloc_free(r);
		return false;
	}

	pull->flags |= LIBNDR_FLAG_REF_ALLOC;
	if (p->endian) {
		pull->flags |= LIBNDR_FLAG_BIGENDIAN;
	}
	ndr_err = call->ndr_pull(pull, NDR_IN, r);
	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
		talloc_free(r);
		return false;
	}

	if (DEBUGLEVEL >= 10) {
		NDR_PRINT_FUNCTION_DEBUG(BrowserrServerEnum, NDR_IN, r);
	}

	_BrowserrServerEnum(p, r);

	if (p->fault_state) {
		talloc_free(r);
		/* Return true here, srv_pipe_hnd.c will take care */
		return true;
	}

	if (DEBUGLEVEL >= 10) {
		NDR_PRINT_FUNCTION_DEBUG(BrowserrServerEnum, NDR_OUT | NDR_SET_VALUES, r);
	}

	push = ndr_push_init_ctx(r);
	if (push == NULL) {
		talloc_free(r);
		return false;
	}

	/*
	 * carry over the pointer count to the reply in case we are
	 * using full pointer. See NDR specification for full pointers
	 */
	push->ptr_count = pull->ptr_count;

	ndr_err = call->ndr_push(push, NDR_OUT, r);
	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
		talloc_free(r);
		return false;
	}

	p->out_data.rdata = ndr_push_blob(push);
	talloc_steal(p->mem_ctx, p->out_data.rdata.data);

	talloc_free(r);

	return true;
}
Beispiel #21
0
/**
   \details Establishes a new Session Context with the server on the
   exchange_emsmdb pipe using 0xA EcDoConnectEx opnum

   \param mem_ctx pointer to the memory context
   \param session pointer to the MAPI session context
   \param p pointer to the DCERPC pipe
   \param cred pointer to the user credentials
   \param return_value pointer on EcDoConnectEx MAPI return value

   \return an allocated emsmdb_context structure on success, otherwise
   NULL
 */
struct emsmdb_context *emsmdb_connect_ex(TALLOC_CTX *mem_ctx,
					 struct mapi_session *session,
					 struct dcerpc_pipe *p,
					 struct cli_credentials *cred,
					 int *return_value)
{
	TALLOC_CTX		*tmp_ctx;
	struct EcDoConnectEx	r;
	struct emsmdb_context	*ctx;
	NTSTATUS		status;
	enum MAPISTATUS		retval;
	uint32_t		pulTimeStamp = 0;
	uint32_t		pcbAuxOut = 0x00001008;
	struct mapi2k7_AuxInfo	*rgbAuxOut;

	/* Sanity Checks */
	if (!session) return NULL;
	if (!p) return NULL;
	if (!cred) return NULL;
	if (!return_value) return NULL;

	tmp_ctx = talloc_named(mem_ctx, 0, "emsmdb_connect_ex");

	ctx = talloc_zero(mem_ctx, struct emsmdb_context);
	ctx->rpc_connection = p;
	ctx->mem_ctx = mem_ctx;

	ctx->info.szDisplayName = NULL;
	ctx->info.szDNPrefix = NULL;
	
	r.out.handle = &ctx->handle;

	r.in.szUserDN = session->profile->mailbox;
	r.in.ulFlags = 0x00000000;
	r.in.ulConMod = emsmdb_hash(r.in.szUserDN);
	r.in.cbLimit = 0x00000000;
	r.in.ulCpid = session->profile->codepage;
	r.in.ulLcidString = session->profile->language;
	r.in.ulLcidSort = session->profile->method;
	r.in.ulIcxrLink = 0xFFFFFFFF;
	r.in.usFCanConvertCodePages = 0x1;

	r.out.szDNPrefix = (const char **) &ctx->info.szDNPrefix;
	r.out.szDisplayName = (const char **) &ctx->info.szDisplayName;
	r.out.pcmsPollsMax = &ctx->info.pcmsPollsMax;
	r.out.pcRetry = &ctx->info.pcRetry;
	r.out.pcmsRetryDelay = &ctx->info.pcmsRetryDelay;
	r.out.picxr = &ctx->info.picxr;
	r.out.pulTimeStamp = &pulTimeStamp;

	r.in.rgwClientVersion[0] = 0x000c;
	r.in.rgwClientVersion[1] = 0x183e;
	r.in.rgwClientVersion[2] = 0x03e8;
	r.in.pulTimeStamp = &pulTimeStamp;
	r.in.rgbAuxIn = NULL;
	r.in.cbAuxIn = 0x00000000;

	rgbAuxOut = talloc_zero(ctx->mem_ctx, struct mapi2k7_AuxInfo);
	rgbAuxOut->AUX_HEADER = NULL;
	r.out.rgbAuxOut = rgbAuxOut;

	r.in.pcbAuxOut = &pcbAuxOut;
	r.out.pcbAuxOut = &pcbAuxOut;

	status = dcerpc_EcDoConnectEx_r(p->binding_handle, tmp_ctx, &r);
	retval = r.out.result;
	if (!NT_STATUS_IS_OK(status) || retval) {
		*return_value = retval;
		mapi_errstr("EcDoConnectEx", retval);
		talloc_free(tmp_ctx);
		return NULL;
	}

	ctx->info.szDisplayName = talloc_steal(mem_ctx, ctx->info.szDisplayName);
	ctx->info.szDNPrefix = talloc_steal(mem_ctx, ctx->info.szDNPrefix);

	ctx->info.rgwServerVersion[0] = r.out.rgwServerVersion[0];
	ctx->info.rgwServerVersion[1] = r.out.rgwServerVersion[1];
	ctx->info.rgwServerVersion[2] = r.out.rgwServerVersion[2];
	
	ctx->cred = cred;
	ctx->max_data = 0xFFF0;
	ctx->setup = false;

	talloc_free(tmp_ctx);
	return ctx;
}
/**
   \details Add a property value to a DATA blob. This convenient
   function should be used when creating a GetPropertiesSpecific reply
   response blob.

   \param mem_ctx pointer to the memory context
   \param property the property tag which value is meant to be
   appended to the blob
   \param value generic pointer on the property value
   \param blob the data blob the function uses to return the blob
   \param layout whether values should be prefixed by a layout
   \param flagged define if the properties are flagged or not

   \note blob.length must be set to 0 before this function is called
   the first time. Also the function only supports a limited set of
   property types at the moment.

   \return 0 on success;
 */
_PUBLIC_ int libmapiserver_push_property(TALLOC_CTX *mem_ctx,
					 uint32_t property, 
					 const void *value, 
					 DATA_BLOB *blob,
					 uint8_t layout, 
					 uint8_t flagged,
					 uint8_t untyped)
{
	struct ndr_push		*ndr;
        struct SBinary_short    bin;
        struct BinaryArray_r    *bin_array;
	uint32_t		i;
	
	ndr = ndr_push_init_ctx(mem_ctx);
	ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN);
	ndr->offset = 0;
	if (blob->length) {
		talloc_free(ndr->data);
		ndr->data = blob->data;
		ndr->offset = blob->length;
	}

	/* Step 1. Is the property typed */
	if (untyped) {
		ndr_push_uint16(ndr, NDR_SCALARS, property & 0xFFFF);
	}



	/* Step 2. Is the property flagged */
	if (flagged) {
		switch (property & 0xFFFF) {
		case PT_ERROR:
			switch (layout) {
			case 0x1:
				ndr_push_uint8(ndr, NDR_SCALARS, layout);
				goto end;
			case PT_ERROR:
				ndr_push_uint8(ndr, NDR_SCALARS, PT_ERROR);
				break;
			}
			break;
		default:
			ndr_push_uint8(ndr, NDR_SCALARS, 0x0);
			break;
		}
	} else {
		/* Step 3. Set the layout */
		if (layout) {
			switch (property & 0xFFFF) {
			case PT_ERROR:
				ndr_push_uint8(ndr, NDR_SCALARS, PT_ERROR);
				break;
			default:
				ndr_push_uint8(ndr, NDR_SCALARS, 0x0);
			}
		}
	}

	/* Step 3. Push property data if supported */
	switch (property & 0xFFFF) {
	case PT_I2:
		ndr_push_uint16(ndr, NDR_SCALARS, *(uint16_t *) value);
		break;
	case PT_LONG:
	case PT_ERROR:
	case PT_OBJECT:
		ndr_push_uint32(ndr, NDR_SCALARS, *(uint32_t *) value);
		break;
	case PT_DOUBLE:
		ndr_push_double(ndr, NDR_SCALARS, *(double *) value);
		break;
	case PT_I8:
		ndr_push_dlong(ndr, NDR_SCALARS, *(uint64_t *) value);
		break;
	case PT_BOOLEAN:
		ndr_push_uint8(ndr, NDR_SCALARS, *(uint8_t *) value);
		break;
	case PT_STRING8:
		ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM|LIBNDR_FLAG_STR_ASCII);
		ndr_push_string(ndr, NDR_SCALARS, (char *) value);
		break;
	case PT_UNICODE:
		ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM);
		ndr_push_string(ndr, NDR_SCALARS, (char *) value);
		break;
	case PT_BINARY:
	case PT_SVREID:
                /* PropertyRow expect a 16 bit header for BLOB in RopQueryRows and RopGetPropertiesSpecific */
		bin.cb = ((struct Binary_r *) value)->cb;
		bin.lpb = ((struct Binary_r *) value)->lpb;
		ndr_push_SBinary_short(ndr, NDR_SCALARS, &bin);
		break;
	case PT_CLSID:
		ndr_push_GUID(ndr, NDR_SCALARS, (struct GUID *) value);
		break;
	case PT_SYSTIME:
		ndr_push_FILETIME(ndr, NDR_SCALARS, (struct FILETIME *) value);
		break;

	case PT_MV_LONG:
		ndr_push_mapi_MV_LONG_STRUCT(ndr, NDR_SCALARS, (struct mapi_MV_LONG_STRUCT *) value);
		break;

	case PT_MV_UNICODE:
                ndr_push_mapi_SLPSTRArrayW(ndr, NDR_SCALARS, (struct mapi_SLPSTRArrayW *) value);
		break;

	case PT_MV_BINARY:
		bin_array = (struct BinaryArray_r *) value;
		ndr_push_uint32(ndr, NDR_SCALARS, bin_array->cValues);
		for (i = 0; i < bin_array->cValues; i++) {
			bin.cb = bin_array->lpbin[i].cb;
			bin.lpb = bin_array->lpbin[i].lpb;
			ndr_push_SBinary_short(ndr, NDR_SCALARS, &bin);
		}
		break;
	default:
		if (property != 0) {
			OC_DEBUG(5, "unsupported type: %.4x", (property & 0xffff));
			abort();
		}
		break;
	}
end:
	/* Step 4. Steal ndr context */
	blob->data = ndr->data;
	talloc_steal(mem_ctx, blob->data);
	blob->length = ndr->offset;

	talloc_free(ndr);
	return 0;
}
Beispiel #23
0
static bool api_RemoteActivation(struct pipes_struct *p)
{
	const struct ndr_interface_call *call;
	struct ndr_pull *pull;
	struct ndr_push *push;
	enum ndr_err_code ndr_err;
	struct RemoteActivation *r;

	call = &ndr_table_IRemoteActivation.calls[NDR_REMOTEACTIVATION];

	r = talloc(talloc_tos(), struct RemoteActivation);
	if (r == NULL) {
		return false;
	}

	pull = ndr_pull_init_blob(&p->in_data.data, r);
	if (pull == NULL) {
		talloc_free(r);
		return false;
	}

	pull->flags |= LIBNDR_FLAG_REF_ALLOC;
	if (p->endian) {
		pull->flags |= LIBNDR_FLAG_BIGENDIAN;
	}
	ndr_err = call->ndr_pull(pull, NDR_IN, r);
	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
		talloc_free(r);
		return false;
	}

	if (DEBUGLEVEL >= 10) {
		NDR_PRINT_FUNCTION_DEBUG(RemoteActivation, NDR_IN, r);
	}

	ZERO_STRUCT(r->out);
	r->out.that = talloc_zero(r, struct ORPCTHAT);
	if (r->out.that == NULL) {
		talloc_free(r);
		return false;
	}

	r->out.pOxid = talloc_zero(r, uint64_t);
	if (r->out.pOxid == NULL) {
		talloc_free(r);
		return false;
	}

	r->out.pdsaOxidBindings = talloc_zero(r, struct DUALSTRINGARRAY);
	if (r->out.pdsaOxidBindings == NULL) {
		talloc_free(r);
		return false;
	}

	r->out.ipidRemUnknown = talloc_zero(r, struct GUID);
	if (r->out.ipidRemUnknown == NULL) {
		talloc_free(r);
		return false;
	}

	r->out.AuthnHint = talloc_zero(r, uint32_t);
	if (r->out.AuthnHint == NULL) {
		talloc_free(r);
		return false;
	}

	r->out.ServerVersion = talloc_zero(r, struct COMVERSION);
	if (r->out.ServerVersion == NULL) {
		talloc_free(r);
		return false;
	}

	r->out.hr = talloc_zero(r, WERROR);
	if (r->out.hr == NULL) {
		talloc_free(r);
		return false;
	}

	r->out.ifaces = talloc_zero_array(r, struct MInterfacePointer *, r->in.Interfaces);
	if (r->out.ifaces == NULL) {
		talloc_free(r);
		return false;
	}

	r->out.results = talloc_zero_array(r, WERROR, r->in.Interfaces);
	if (r->out.results == NULL) {
		talloc_free(r);
		return false;
	}

	r->out.result = _RemoteActivation(p, r);

	if (p->fault_state) {
		talloc_free(r);
		/* Return true here, srv_pipe_hnd.c will take care */
		return true;
	}

	if (DEBUGLEVEL >= 10) {
		NDR_PRINT_FUNCTION_DEBUG(RemoteActivation, NDR_OUT | NDR_SET_VALUES, r);
	}

	push = ndr_push_init_ctx(r);
	if (push == NULL) {
		talloc_free(r);
		return false;
	}

	/*
	 * carry over the pointer count to the reply in case we are
	 * using full pointer. See NDR specification for full pointers
	 */
	push->ptr_count = pull->ptr_count;

	ndr_err = call->ndr_push(push, NDR_OUT, r);
	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
		talloc_free(r);
		return false;
	}

	p->out_data.rdata = ndr_push_blob(push);
	talloc_steal(p->mem_ctx, p->out_data.rdata.data);

	talloc_free(r);

	return true;
}
Beispiel #24
0
/* 
   list files in a directory matching a wildcard pattern - old SMBsearch interface
*/
static NTSTATUS pvfs_search_first_old(struct ntvfs_module_context *ntvfs,
				      struct ntvfs_request *req, union smb_search_first *io, 
				      void *search_private, 
				      bool (*callback)(void *, const union smb_search_data *))
{
	struct pvfs_dir *dir;
	struct pvfs_state *pvfs = talloc_get_type(ntvfs->private_data,
				  struct pvfs_state);
	struct pvfs_search_state *search;
	uint_t reply_count;
	uint16_t search_attrib;
	const char *pattern;
	NTSTATUS status;
	struct pvfs_filename *name;
	int id;

	search_attrib = io->search_first.in.search_attrib;
	pattern       = io->search_first.in.pattern;

	/* resolve the cifs name to a posix name */
	status = pvfs_resolve_name(pvfs, req, pattern, PVFS_RESOLVE_WILDCARD, &name);
	if (!NT_STATUS_IS_OK(status)) {
		return status;
	}

	if (!name->has_wildcard && !name->exists) {
		return STATUS_NO_MORE_FILES;
	}

	status = pvfs_access_check_parent(pvfs, req, name, SEC_DIR_TRAVERSE | SEC_DIR_LIST);
	if (!NT_STATUS_IS_OK(status)) {
		return status;
	}

	/* we initially make search a child of the request, then if we
	   need to keep it long term we steal it for the private
	   structure */
	search = talloc(req, struct pvfs_search_state);
	if (!search) {
		return NT_STATUS_NO_MEMORY;
	}

	/* do the actual directory listing */
	status = pvfs_list_start(pvfs, name, search, &dir);
	if (!NT_STATUS_IS_OK(status)) {
		return status;
	}

	/* we need to give a handle back to the client so it
	   can continue a search */
	id = idr_get_new(pvfs->search.idtree, search, MAX_OLD_SEARCHES);
	if (id == -1) {
		pvfs_search_cleanup(pvfs);
		id = idr_get_new(pvfs->search.idtree, search, MAX_OLD_SEARCHES);
	}
	if (id == -1) {
		return NT_STATUS_INSUFFICIENT_RESOURCES;
	}

	search->pvfs = pvfs;
	search->handle = id;
	search->dir = dir;
	search->current_index = 0;
	search->search_attrib = search_attrib & 0xFF;
	search->must_attrib = (search_attrib>>8) & 0xFF;
	search->last_used = time(NULL);
	search->te = NULL;

	DLIST_ADD(pvfs->search.list, search);

	talloc_set_destructor(search, pvfs_search_destructor);

	status = pvfs_search_fill(pvfs, req, io->search_first.in.max_count, search, io->generic.data_level,
				  &reply_count, search_private, callback);
	if (!NT_STATUS_IS_OK(status)) {
		return status;
	}

	io->search_first.out.count = reply_count;

	/* not matching any entries is an error */
	if (reply_count == 0) {
		return STATUS_NO_MORE_FILES;
	}

	talloc_steal(pvfs, search);

	return NT_STATUS_OK;
}
Beispiel #25
0
/** Load clients from LDAP on server start
 *
 * @param[in] inst rlm_ldap configuration.
 * @param[in] cs to load client attribute/LDAP attribute mappings from.
 * @return -1 on error else 0.
 */
CC_HINT(nonnull) int rlm_ldap_client_load(ldap_instance_t const *inst, CONF_SECTION *cs)
{
	int 		ret = 0;
	ldap_rcode_t	status;
	ldap_handle_t	*conn = NULL;

	char const	**attrs = NULL;

	CONF_PAIR	*cp;
	int		count = 0, idx = 0;

	LDAPMessage	*result = NULL;
	LDAPMessage	*entry;
	char		*dn = NULL;

	RADCLIENT	*c;

	LDAP_DBG("Loading dynamic clients");

	rad_assert(inst->clientobj_base_dn);

	if (!inst->clientobj_filter) {
		LDAP_ERR("Told to load clients but 'client.filter' not specified");

		return -1;
	}

	count = cf_pair_count(cs);
	count++;

	/*
	 *	Create an array of LDAP attributes to feed to rlm_ldap_search.
	 */
	attrs = talloc_array(inst, char const *, count);
	if (rlm_ldap_client_get_attrs(attrs, &idx, cs) < 0) return -1;

	conn = rlm_ldap_get_socket(inst, NULL);
	if (!conn) return -1;

	/*
	 *	Perform all searches as the admin user.
	 */
	if (conn->rebound) {
		status = rlm_ldap_bind(inst, NULL, &conn, inst->admin_dn, inst->password, true);
		if (status != LDAP_PROC_SUCCESS) {
			ret = -1;
			goto finish;
		}

		rad_assert(conn);

		conn->rebound = false;
	}

	status = rlm_ldap_search(inst, NULL, &conn, inst->clientobj_base_dn, inst->clientobj_scope,
				 inst->clientobj_filter, attrs, &result);
	switch (status) {
	case LDAP_PROC_SUCCESS:
		break;

	case LDAP_PROC_NO_RESULT:
		LDAP_INFO("No clients were found in the directory");
		ret = 0;
		goto finish;

	default:
		ret = -1;
		goto finish;
	}

	rad_assert(conn);
	entry = ldap_first_entry(conn->handle, result);
	if (!entry) {
		int ldap_errno;

		ldap_get_option(conn->handle, LDAP_OPT_RESULT_CODE, &ldap_errno);
		LDAP_ERR("Failed retrieving entry: %s", ldap_err2string(ldap_errno));

		ret = -1;
		goto finish;
	}

	do {
		CONF_SECTION *cc;
		char *id;

		char **value;

		id = dn = ldap_get_dn(conn->handle, entry);
		cp = cf_pair_find(cs, "identifier");
		if (cp) {
			value = ldap_get_values(conn->handle, entry, cf_pair_value(cp));
			if (value) id = value[0];
		}

		/*
		 *	Iterate over mapping sections
		 */
		cc = cf_section_alloc(NULL, "client", id);
		if (rlm_ldap_client_map_section(inst, cc, cs, conn, entry) < 0) {
			talloc_free(cc);
			ret = -1;
			goto finish;
		}

		/*
		 *@todo these should be parented from something
		 */
		c = client_afrom_cs(NULL, cc, false);
		if (!c) {
			talloc_free(cc);
			ret = -1;
			goto finish;
		}

		/*
		 *	Client parents the CONF_SECTION which defined it
		 */
		talloc_steal(c, cc);

		if (!client_add(NULL, c)) {
			LDAP_ERR("Failed to add client \"%s\", possible duplicate?", dn);
			ret = -1;
			client_free(c);
			goto finish;
		}

		LDAP_DBG("Client \"%s\" added", dn);

		ldap_memfree(dn);
		dn = NULL;
	} while ((entry = ldap_next_entry(conn->handle, entry)));

finish:
	talloc_free(attrs);
	if (dn) ldap_memfree(dn);
	if (result) ldap_msgfree(result);

	rlm_ldap_release_socket(inst, conn);

	return ret;
}
Beispiel #26
0
/* 
   list files in a directory matching a wildcard pattern
*/
static NTSTATUS pvfs_search_first_trans2(struct ntvfs_module_context *ntvfs,
					 struct ntvfs_request *req, union smb_search_first *io, 
					 void *search_private, 
					 bool (*callback)(void *, const union smb_search_data *))
{
	struct pvfs_dir *dir;
	struct pvfs_state *pvfs = talloc_get_type(ntvfs->private_data,
				  struct pvfs_state);
	struct pvfs_search_state *search;
	uint_t reply_count;
	uint16_t search_attrib, max_count;
	const char *pattern;
	NTSTATUS status;
	struct pvfs_filename *name;
	int id;

	search_attrib = io->t2ffirst.in.search_attrib;
	pattern       = io->t2ffirst.in.pattern;
	max_count     = io->t2ffirst.in.max_count;

	/* resolve the cifs name to a posix name */
	status = pvfs_resolve_name(pvfs, req, pattern, PVFS_RESOLVE_WILDCARD, &name);
	if (!NT_STATUS_IS_OK(status)) {
		return status;
	}

	if (!name->has_wildcard && !name->exists) {
		return NT_STATUS_NO_SUCH_FILE;
	}

	status = pvfs_access_check_parent(pvfs, req, name, SEC_DIR_TRAVERSE | SEC_DIR_LIST);
	if (!NT_STATUS_IS_OK(status)) {
		return status;
	}

	/* we initially make search a child of the request, then if we
	   need to keep it long term we steal it for the private
	   structure */
	search = talloc(req, struct pvfs_search_state);
	if (!search) {
		return NT_STATUS_NO_MEMORY;
	}

	/* do the actual directory listing */
	status = pvfs_list_start(pvfs, name, search, &dir);
	if (!NT_STATUS_IS_OK(status)) {
		return status;
	}

	id = idr_get_new(pvfs->search.idtree, search, MAX_SEARCH_HANDLES);
	if (id == -1) {
		return NT_STATUS_INSUFFICIENT_RESOURCES;
	}

	search->pvfs = pvfs;
	search->handle = id;
	search->dir = dir;
	search->current_index = 0;
	search->search_attrib = search_attrib;
	search->must_attrib = 0;
	search->last_used = 0;
	search->num_ea_names = io->t2ffirst.in.num_names;
	search->ea_names = io->t2ffirst.in.ea_names;
	search->te = NULL;

	DLIST_ADD(pvfs->search.list, search);
	talloc_set_destructor(search, pvfs_search_destructor);

	status = pvfs_search_fill(pvfs, req, max_count, search, io->generic.data_level,
				  &reply_count, search_private, callback);
	if (!NT_STATUS_IS_OK(status)) {
		return status;
	}

	/* not matching any entries is an error */
	if (reply_count == 0) {
		return NT_STATUS_NO_SUCH_FILE;
	}

	io->t2ffirst.out.count = reply_count;
	io->t2ffirst.out.handle = search->handle;
	io->t2ffirst.out.end_of_search = pvfs_list_eos(dir, search->current_index) ? 1 : 0;

	/* work out if we are going to keep the search state
	   and allow for a search continue */
	if ((io->t2ffirst.in.flags & FLAG_TRANS2_FIND_CLOSE) ||
	    ((io->t2ffirst.in.flags & FLAG_TRANS2_FIND_CLOSE_IF_END) && 
	     io->t2ffirst.out.end_of_search)) {
		talloc_free(search);
	} else {
		talloc_steal(pvfs, search);
	}

	return NT_STATUS_OK;
}
Beispiel #27
0
static krb5_error_code principals_from_list(TALLOC_CTX *parent_ctx,
					const char *samAccountName,
					const char *realm,
					const char **SPNs, int num_SPNs,
					krb5_context context,
					krb5_principal **principals_out,
					const char **error_string)
{
	unsigned int i;
	krb5_error_code ret;
	char *upper_realm;
	TALLOC_CTX *tmp_ctx;
	krb5_principal *principals = NULL;
	tmp_ctx = talloc_new(parent_ctx);
	if (!tmp_ctx) {
		*error_string = "Cannot allocate tmp_ctx";
		return ENOMEM;
	}

	if (!realm) {
		*error_string = "Cannot make principal without a realm";
		ret = EINVAL;
		goto done;
	}

	upper_realm = strupper_talloc(tmp_ctx, realm);
	if (!upper_realm) {
		*error_string = "Cannot allocate full upper case realm";
		ret = ENOMEM;
		goto done;
	}

	principals = talloc_zero_array(tmp_ctx, krb5_principal,
					num_SPNs ? (num_SPNs + 2) : 2);

	for (i = 0; num_SPNs && i < num_SPNs; i++) {
		ret = krb5_parse_name(context, SPNs[i], &principals[i]);

		if (ret) {
			*error_string = smb_get_krb5_error_message(context, ret,
								   parent_ctx);
			goto done;
		}
	}

	if (samAccountName) {
		ret = krb5_make_principal(context, &principals[i],
					  upper_realm, samAccountName,
					  NULL);
		if (ret) {
			*error_string = smb_get_krb5_error_message(context, ret,
								   parent_ctx);
			goto done;
		}
	}

done:
	if (ret) {
		keytab_principals_free(context, principals);
	} else {
		*principals_out = talloc_steal(parent_ctx, principals);
	}
	talloc_free(tmp_ctx);
	return ret;
}
Beispiel #28
0
static NTSTATUS pvfs_search_first_smb2(struct ntvfs_module_context *ntvfs,
				       struct ntvfs_request *req, const struct smb2_find *io, 
				       void *search_private, 
				       bool (*callback)(void *, const union smb_search_data *))
{
	struct pvfs_dir *dir;
	struct pvfs_state *pvfs = talloc_get_type(ntvfs->private_data,
				  struct pvfs_state);
	struct pvfs_search_state *search;
	uint_t reply_count;
	uint16_t max_count;
	const char *pattern;
	NTSTATUS status;
	struct pvfs_filename *name;
	struct pvfs_file *f;

	f = pvfs_find_fd(pvfs, req, io->in.file.ntvfs);
	if (!f) {
		return NT_STATUS_FILE_CLOSED;
	}

	/* its only valid for directories */
	if (f->handle->fd != -1) {
		return NT_STATUS_INVALID_PARAMETER;
	}

	if (!(f->access_mask & SEC_DIR_LIST)) {
		return NT_STATUS_ACCESS_DENIED;
	}

	if (f->search) {
		talloc_free(f->search);
		f->search = NULL;
	}

	if (strequal(io->in.pattern, "")) {
		return NT_STATUS_OBJECT_NAME_INVALID;
	}
	if (strchr_m(io->in.pattern, '\\')) {
		return NT_STATUS_OBJECT_NAME_INVALID;
	}
	if (strchr_m(io->in.pattern, '/')) {
		return NT_STATUS_OBJECT_NAME_INVALID;
	}

	if (strequal("", f->handle->name->original_name)) {
		pattern = talloc_asprintf(req, "\\%s", io->in.pattern);
		NT_STATUS_HAVE_NO_MEMORY(pattern);
	} else {
		pattern = talloc_asprintf(req, "\\%s\\%s",
					  f->handle->name->original_name,
					  io->in.pattern);
		NT_STATUS_HAVE_NO_MEMORY(pattern);
	}

	/* resolve the cifs name to a posix name */
	status = pvfs_resolve_name(pvfs, req, pattern, PVFS_RESOLVE_WILDCARD, &name);
	NT_STATUS_NOT_OK_RETURN(status);

	if (!name->has_wildcard && !name->exists) {
		return NT_STATUS_NO_SUCH_FILE;
	}

	/* we initially make search a child of the request, then if we
	   need to keep it long term we steal it for the private
	   structure */
	search = talloc(req, struct pvfs_search_state);
	NT_STATUS_HAVE_NO_MEMORY(search);

	/* do the actual directory listing */
	status = pvfs_list_start(pvfs, name, search, &dir);
	NT_STATUS_NOT_OK_RETURN(status);

	search->pvfs		= pvfs;
	search->handle		= INVALID_SEARCH_HANDLE;
	search->dir		= dir;
	search->current_index	= 0;
	search->search_attrib	= 0x0000FFFF;
	search->must_attrib	= 0;
	search->last_used	= 0;
	search->num_ea_names	= 0;
	search->ea_names	= NULL;
	search->te		= NULL;

	if (io->in.continue_flags & SMB2_CONTINUE_FLAG_SINGLE) {
		max_count = 1;
	} else {
		max_count = UINT16_MAX;
	}

	status = pvfs_search_fill(pvfs, req, max_count, search, io->data_level,
				  &reply_count, search_private, callback);
	NT_STATUS_NOT_OK_RETURN(status);

	/* not matching any entries is an error */
	if (reply_count == 0) {
		return NT_STATUS_NO_SUCH_FILE;
	}

	f->search = talloc_steal(f, search);

	return NT_STATUS_OK;
}
Beispiel #29
0
/**
 * open connection so SAMR + Join Domain
 * common code needed when adding or removing users
 */
static enum MAPISTATUS mapiadmin_samr_connect(struct mapiadmin_ctx *mapiadmin_ctx,
					      TALLOC_CTX *mem_ctx)
{
	NTSTATUS			status;
	struct tevent_context		*ev;
	struct mapi_context		*mapi_ctx;
	struct mapi_profile		*profile;
	struct samr_Connect		c;
	struct samr_OpenDomain		o;
	struct samr_LookupDomain	l;
	struct policy_handle		handle;
	struct policy_handle		domain_handle;
	struct lsa_String		name;

	MAPI_RETVAL_IF(!mapiadmin_ctx, MAPI_E_NOT_INITIALIZED, NULL);
	MAPI_RETVAL_IF(!mapiadmin_ctx->session, MAPI_E_NOT_INITIALIZED, NULL);
	MAPI_RETVAL_IF(!mapiadmin_ctx->session->profile, MAPI_E_NOT_INITIALIZED, NULL);
	MAPI_RETVAL_IF(!mapiadmin_ctx->session->profile->credentials, MAPI_E_NOT_INITIALIZED, NULL);
	MAPI_RETVAL_IF(!mapiadmin_ctx->username, MAPI_E_NOT_INITIALIZED, NULL);

	mapi_ctx = mapiadmin_ctx->session->mapi_ctx;
	MAPI_RETVAL_IF(!mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);

	profile = mapiadmin_ctx->session->profile;
	
	mapiadmin_ctx->user_ctx = talloc_zero(mem_ctx, struct test_join);
	MAPI_RETVAL_IF(!mapiadmin_ctx->user_ctx, MAPI_E_NOT_ENOUGH_RESOURCES ,NULL);

	DEBUG(3, ("Connecting to SAMR\n"));

	ev = tevent_context_init(mem_ctx);

	status = dcerpc_pipe_connect(mapiadmin_ctx->user_ctx,
				     &mapiadmin_ctx->user_ctx->p,
				     mapiadmin_ctx->dc_binding ? 
				     mapiadmin_ctx->dc_binding : 
				     mapiadmin_ctx->binding,
				     &ndr_table_samr,
				     profile->credentials, ev, mapi_ctx->lp_ctx);
					     
	MAPI_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, NULL);	

	profile = mapiadmin_ctx->session->profile;

	c.in.system_name = NULL;
	c.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
	c.out.connect_handle = &handle;

	status = dcerpc_samr_Connect_r(mapiadmin_ctx->user_ctx->p->binding_handle, mapiadmin_ctx->user_ctx, &c);
	if (!NT_STATUS_IS_OK(status)) {
		const char *errstr = nt_errstr(status);
		if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
			errstr = dcerpc_errstr(mapiadmin_ctx->user_ctx, mapiadmin_ctx->user_ctx->p->last_fault_code);
		}
		DEBUG(3, ("samr_Connect failed - %s\n", errstr));
		return MAPI_E_CALL_FAILED;
	}

	DEBUG(3, ("Opening domain %s\n", profile->domain));

	name.string = profile->domain;
	l.in.connect_handle = &handle;
	l.in.domain_name = &name;

	l.out.sid = talloc(mem_ctx, struct dom_sid2 *);
	talloc_steal(mapiadmin_ctx->user_ctx, l.out.sid);

	status = dcerpc_samr_LookupDomain_r(mapiadmin_ctx->user_ctx->p->binding_handle, mapiadmin_ctx->user_ctx, &l);
	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(3, ("LookupDomain failed - %s\n", nt_errstr(status)));
		return MAPI_E_CALL_FAILED;
	}

	mapiadmin_ctx->user_ctx->dom_sid = *l.out.sid;
	mapiadmin_ctx->user_ctx->dom_netbios_name = talloc_strdup(mapiadmin_ctx->user_ctx, profile->domain);
	if (!mapiadmin_ctx->user_ctx->dom_netbios_name) return MAPI_E_CALL_FAILED;

	o.in.connect_handle = &handle;
	o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
	o.in.sid = *l.out.sid;
	o.out.domain_handle = &domain_handle;

	status = dcerpc_samr_OpenDomain_r(mapiadmin_ctx->user_ctx->p->binding_handle, mapiadmin_ctx->user_ctx, &o);
	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(3, ("OpenDomain failed - %s\n", nt_errstr(status)));
		return MAPI_E_CALL_FAILED;
	}

	mapiadmin_ctx->handle = talloc_memdup(mem_ctx, &domain_handle, sizeof (struct policy_handle));

	errno = 0;
	return MAPI_E_SUCCESS;
}
Beispiel #30
0
int cddb_resolve(const char *dev, char **xmcd_file)
{
    char cddb_cache_dir[] = DEFAULT_CACHE_DIR;
    char *home_dir = NULL;
    cddb_data_t cddb_data;
    void *talloc_ctx = talloc_new(NULL);

    if (cdtoc_last_track <= 0) {
        cdtoc_last_track = read_toc(dev);
        if (cdtoc_last_track < 0) {
            mp_tmsg(MSGT_OPEN, MSGL_ERR, "Failed to open %s device.\n", dev);
            return -1;
        }
    }
    cddb_data.tracks    = cdtoc_last_track;
    cddb_data.disc_id   = cddb_discid(cddb_data.tracks);
    cddb_data.anonymous = 1;    // Don't send user info by default

    mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_CDDB_DISCID=%08lx\n",
           cddb_data.disc_id);

    // Check if there is a CD in the drive
    // FIXME: That's not really a good way to check
    if (cddb_data.disc_id == 0) {
        mp_tmsg(MSGT_DEMUX, MSGL_ERR, "No CD in the drive.\n");
        return -1;
    }

    home_dir = getenv("HOME");
#ifdef __MINGW32__
    if (home_dir == NULL)
        home_dir = getenv("USERPROFILE");
    if (home_dir == NULL)
        home_dir = getenv("HOMEPATH");
    // Last resort, store the cddb cache in the mplayer directory
    if (home_dir == NULL)
        home_dir = (char *)talloc_steal(talloc_ctx,
                                        mp_find_user_config_file(""));
#endif
    if (home_dir == NULL) {
        cddb_data.cache_dir = NULL;
    } else {
        unsigned len = strlen(home_dir) + strlen(cddb_cache_dir) + 1;
        cddb_data.cache_dir = malloc(len);
        if (cddb_data.cache_dir == NULL) {
            mp_tmsg(MSGT_DEMUX, MSGL_ERR, "Memory allocation failed.\n");
            talloc_free(talloc_ctx);
            return -1;
        }
        snprintf(cddb_data.cache_dir, len, "%s%s", home_dir, cddb_cache_dir);
    }
    talloc_free(talloc_ctx);

    // Check for a cached file
    if (cddb_read_cache(&cddb_data) < 0) {
        // No Cache found
        if (cddb_retrieve(&cddb_data) < 0) {
            return -1;
        }
    }

    if (cddb_data.xmcd_file != NULL) {
//        printf("%s\n", cddb_data.xmcd_file);
        *xmcd_file = cddb_data.xmcd_file;
        return 0;
    }

    return -1;
}