Exemplo n.º 1
0
_PUBLIC_ void cli_credentials_parse_string(struct cli_credentials *credentials, const char *data, enum credentials_obtained obtained)
{
	char *uname, *p;

	if (strcmp("%",data) == 0) {
		cli_credentials_set_anonymous(credentials);
		return;
	}

	uname = talloc_strdup(credentials, data); 
	if ((p = strchr_m(uname,'%'))) {
		*p = 0;
		cli_credentials_set_password(credentials, p+1, obtained);
	}

	if ((p = strchr_m(uname,'@'))) {
		cli_credentials_set_principal(credentials, uname, obtained);
		*p = 0;
		cli_credentials_set_realm(credentials, p+1, obtained);
		return;
	} else if ((p = strchr_m(uname,'\\')) || (p = strchr_m(uname, '/'))) {
		*p = 0;
		cli_credentials_set_domain(credentials, uname, obtained);
		uname = p+1;
	}
	cli_credentials_set_username(credentials, uname, obtained);
}
Exemplo n.º 2
0
/**
 * Create a new anonymous credential
 * @param mem_ctx TALLOC_CTX parent for credentials structure 
 */
_PUBLIC_ struct cli_credentials *cli_credentials_init_anon(TALLOC_CTX *mem_ctx)
{
	struct cli_credentials *anon_credentials;

	anon_credentials = cli_credentials_init(mem_ctx);
	cli_credentials_set_anonymous(anon_credentials);

	return anon_credentials;
}
Exemplo n.º 3
0
static int ejs_net_context(MprVarHandle eid, int argc, struct MprVar **argv)
{
	TALLOC_CTX *event_mem_ctx = talloc_new(mprMemCtx());
	struct cli_credentials *creds;
	struct libnet_context *ctx;
	struct MprVar obj;
	struct event_context *ev;

	if (!event_mem_ctx) {
		ejsSetErrorMsg(eid, "talloc_new() failed");
		return -1;
	}
	ev = event_context_find(event_mem_ctx);
	ctx = libnet_context_init(ev);
	/* IF we generated a new event context, it will be under here,
	 * and we need it to last as long as the libnet context, so
	 * make it a child */
	talloc_steal(ctx, event_mem_ctx);

	if (argc == 0 || (argc == 1 && argv[0]->type == MPR_TYPE_NULL)) {
		creds = cli_credentials_init(ctx);
		if (creds == NULL) {
			ejsSetErrorMsg(eid, "cli_credential_init() failed");
			talloc_free(ctx);
			return -1;
		}
		cli_credentials_set_conf(creds);
		cli_credentials_set_anonymous(creds);
	} else if (argc == 1 && argv[0]->type == MPR_TYPE_OBJECT) {
		/* get credential values from credentials object */
		creds = mprGetPtr(argv[0], "creds");
		if (creds == NULL) {
			ejsSetErrorMsg(eid, "userAuth requires a 'creds' first parameter");
			talloc_free(ctx);
			return -1;
		}
	} else {
		ejsSetErrorMsg(eid, "NetContext invalid arguments, this function requires an object.");
		talloc_free(ctx);
		return -1;
	}
	ctx->cred = creds;

	obj = mprObject("NetCtx");
	mprSetPtrChild(&obj, "ctx", ctx);
	
	mprSetCFunction(&obj, "UserMgr", ejs_net_userman);
	mprSetCFunction(&obj, "JoinDomain", ejs_net_join_domain);
	mprSetCFunction(&obj, "SamSyncLdb", ejs_net_samsync_ldb);
	mpr_Return(eid, obj);

	return 0;
}
Exemplo n.º 4
0
/**
 * Fill in credentials for the machine trust account, from the secrets database.
 *
 * @param cred Credentials structure to fill in
 * @retval NTSTATUS error detailing any failure
 */
_PUBLIC_ NTSTATUS cli_credentials_set_secrets(struct cli_credentials *cred,
					      struct loadparm_context *lp_ctx,
					      struct ldb_context *ldb,
					      const char *base,
					      const char *filter,
					      char **error_string)
{
	NTSTATUS status = cli_credentials_set_secrets_lct(cred, lp_ctx, ldb, base, filter, 0, NULL, error_string);
	if (!NT_STATUS_IS_OK(status)) {
		/* set anonymous as the fallback, if the machine account won't work */
		cli_credentials_set_anonymous(cred);
	}
	return status;
}
Exemplo n.º 5
0
_PUBLIC_ NTSTATUS auth_anonymous_session_info(TALLOC_CTX *parent_ctx, 
				     struct tevent_context *event_ctx, 
				     struct loadparm_context *lp_ctx,
				     struct auth_session_info **_session_info) 
{
	NTSTATUS nt_status;
	struct auth_serversupplied_info *server_info = NULL;
	struct auth_session_info *session_info = NULL;
	TALLOC_CTX *mem_ctx = talloc_new(parent_ctx);
	
	nt_status = auth_anonymous_server_info(mem_ctx,
					       lp_netbios_name(lp_ctx),
					       &server_info);
	if (!NT_STATUS_IS_OK(nt_status)) {
		talloc_free(mem_ctx);
		return nt_status;
	}

	/* references the server_info into the session_info */
	nt_status = auth_generate_session_info(parent_ctx, event_ctx, lp_ctx, server_info, &session_info);
	talloc_free(mem_ctx);

	NT_STATUS_NOT_OK_RETURN(nt_status);

	session_info->credentials = cli_credentials_init(session_info);
	if (!session_info->credentials) {
		return NT_STATUS_NO_MEMORY;
	}

	cli_credentials_set_conf(session_info->credentials, lp_ctx);
	cli_credentials_set_anonymous(session_info->credentials);
	
	*_session_info = session_info;

	return NT_STATUS_OK;
}
Exemplo n.º 6
0
/**
 * Fill in credentials for the machine trust account, from the secrets database.
 * 
 * @param cred Credentials structure to fill in
 * @retval NTSTATUS error detailing any failure
 */
NTSTATUS cli_credentials_set_secrets(struct cli_credentials *cred, 
				     const char *base,
				     const char *filter)
{
	TALLOC_CTX *mem_ctx;
	
	struct ldb_context *ldb;
	int ldb_ret;
	struct ldb_message **msgs;
	const char *attrs[] = {
		"secret",
		"priorSecret",
		"samAccountName",
		"flatname",
		"realm",
		"secureChannelType",
		"ntPwdHash",
		"msDS-KeyVersionNumber",
		"saltPrincipal",
		"privateKeytab",
		"krb5Keytab",
		NULL
	};
	
	const char *machine_account;
	const char *password;
	const char *old_password;
	const char *domain;
	const char *realm;
	enum netr_SchannelType sct;
	const char *salt_principal;
	const char *keytab;
	
	/* ok, we are going to get it now, don't recurse back here */
	cred->machine_account_pending = False;

	/* some other parts of the system will key off this */
	cred->machine_account = True;

	mem_ctx = talloc_named(cred, 0, "cli_credentials fetch machine password");

	/* Local secrets are stored in secrets.ldb */
	ldb = secrets_db_connect(mem_ctx);
	if (!ldb) {
		/* set anonymous as the fallback, if the machine account won't work */
		cli_credentials_set_anonymous(cred);
		DEBUG(1, ("Could not open secrets.ldb\n"));
		return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
	}

	/* search for the secret record */
	ldb_ret = gendb_search(ldb,
			       mem_ctx, ldb_dn_new(mem_ctx, ldb, base), 
			       &msgs, attrs,
			       "%s", filter);
	if (ldb_ret == 0) {
		DEBUG(1, ("Could not find entry to match filter: %s\n",
			  filter));
		/* set anonymous as the fallback, if the machine account won't work */
		cli_credentials_set_anonymous(cred);
		talloc_free(mem_ctx);
		return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
	} else if (ldb_ret != 1) {
		DEBUG(1, ("Found more than one (%d) entry to match filter: %s\n",
			  ldb_ret, filter));
		/* set anonymous as the fallback, if the machine account won't work */
		cli_credentials_set_anonymous(cred);
		talloc_free(mem_ctx);
		return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
	}
	
	password = ldb_msg_find_attr_as_string(msgs[0], "secret", NULL);
	old_password = ldb_msg_find_attr_as_string(msgs[0], "priorSecret", NULL);

	machine_account = ldb_msg_find_attr_as_string(msgs[0], "samAccountName", NULL);

	if (!machine_account) {
		DEBUG(1, ("Could not find 'samAccountName' in join record to domain: %s\n",
			  cli_credentials_get_domain(cred)));
		/* set anonymous as the fallback, if the machine account won't work */
		cli_credentials_set_anonymous(cred);
		talloc_free(mem_ctx);
		return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
	}

	salt_principal = ldb_msg_find_attr_as_string(msgs[0], "saltPrincipal", NULL);
	cli_credentials_set_salt_principal(cred, salt_principal);
	
	sct = ldb_msg_find_attr_as_int(msgs[0], "secureChannelType", 0);
	if (sct) { 
		cli_credentials_set_secure_channel_type(cred, sct);
	}
	
	if (!password) {
		const struct ldb_val *nt_password_hash = ldb_msg_find_ldb_val(msgs[0], "ntPwdHash");
		struct samr_Password hash;
		ZERO_STRUCT(hash);
		if (nt_password_hash) {
			memcpy(hash.hash, nt_password_hash->data, 
			       MIN(nt_password_hash->length, sizeof(hash.hash)));
		
			cli_credentials_set_nt_hash(cred, &hash, CRED_SPECIFIED);
		} else {
			cli_credentials_set_password(cred, NULL, CRED_SPECIFIED);
		}
	} else {
		cli_credentials_set_password(cred, password, CRED_SPECIFIED);
	}

	
	domain = ldb_msg_find_attr_as_string(msgs[0], "flatname", NULL);
	if (domain) {
		cli_credentials_set_domain(cred, domain, CRED_SPECIFIED);
	}

	realm = ldb_msg_find_attr_as_string(msgs[0], "realm", NULL);
	if (realm) {
		cli_credentials_set_realm(cred, realm, CRED_SPECIFIED);
	}

	cli_credentials_set_username(cred, machine_account, CRED_SPECIFIED);

	cli_credentials_set_kvno(cred, ldb_msg_find_attr_as_int(msgs[0], "msDS-KeyVersionNumber", 0));

	/* If there was an external keytab specified by reference in
	 * the LDB, then use this.  Otherwise we will make one up
	 * (chewing CPU time) from the password */
	keytab = ldb_msg_find_attr_as_string(msgs[0], "krb5Keytab", NULL);
	if (keytab) {
		cli_credentials_set_keytab_name(cred, keytab, CRED_SPECIFIED);
	} else {
		keytab = ldb_msg_find_attr_as_string(msgs[0], "privateKeytab", NULL);
		if (keytab) {
			keytab = talloc_asprintf(mem_ctx, "FILE:%s", private_path(mem_ctx, keytab));
			if (keytab) {
				cli_credentials_set_keytab_name(cred, keytab, CRED_SPECIFIED);
			}
		}
	}
	talloc_free(mem_ctx);
	
	return NT_STATUS_OK;
}
Exemplo n.º 7
0
static bool test_schannel_anonymous_setPassword(struct torture_context *tctx,
						uint32_t dcerpc_flags,
						bool use2)
{
	NTSTATUS status, result;
	const char *binding = torture_setting_string(tctx, "binding", NULL);
	struct dcerpc_binding *b;
	struct dcerpc_pipe *p = NULL;
	struct cli_credentials *credentials;
	bool ok = true;

	credentials = cli_credentials_init(NULL);
	torture_assert(tctx, credentials != NULL, "Bad credentials");
	cli_credentials_set_anonymous(credentials);

	status = dcerpc_parse_binding(tctx, binding, &b);
	torture_assert_ntstatus_ok(tctx, status, "Bad binding string");

	status = dcerpc_binding_set_flags(b, dcerpc_flags, DCERPC_AUTH_OPTIONS);
	torture_assert_ntstatus_ok(tctx, status, "set flags");

	status = dcerpc_pipe_connect_b(tctx,
				       &p,
				       b,
				       &ndr_table_netlogon,
				       credentials,
				       tctx->ev,
				       tctx->lp_ctx);
	torture_assert_ntstatus_ok(tctx, status, "Failed to connect without schannel");

	if (use2) {
		struct netr_ServerPasswordSet2 r = {};
		struct netr_Authenticator credential = {};
		struct netr_Authenticator return_authenticator = {};
		struct netr_CryptPassword new_password = {};

		r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
		r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
		r.in.secure_channel_type = 0;
		r.in.computer_name = TEST_MACHINE_NAME;
		r.in.credential = &credential;
		r.in.new_password = &new_password;
		r.out.return_authenticator = &return_authenticator;

		status = dcerpc_netr_ServerPasswordSet2_r(p->binding_handle, tctx, &r);
		result = r.out.result;
	} else {
		struct netr_ServerPasswordSet r = {};
		struct netr_Authenticator credential = {};
		struct netr_Authenticator return_authenticator = {};
		struct samr_Password new_password = {};

		r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
		r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
		r.in.secure_channel_type = 0;
		r.in.computer_name = TEST_MACHINE_NAME;
		r.in.credential = &credential;
		r.in.new_password = &new_password;
		r.out.return_authenticator = &return_authenticator;

		status = dcerpc_netr_ServerPasswordSet_r(p->binding_handle, tctx, &r);
		result = r.out.result;
	}

	torture_assert_ntstatus_ok(tctx, status, "ServerPasswordSet failed");

	if (NT_STATUS_IS_OK(result)) {
		torture_fail(tctx, "unexpectedly received NT_STATUS_OK");
	}

	return ok;
}
Exemplo n.º 8
0
/*
  test session ops
*/
static BOOL test_session(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
{
	NTSTATUS status;
	BOOL ret = True;
	struct smbcli_session *session;
	struct smbcli_session *session2;
	struct smbcli_session *session3;
	struct smbcli_session *session4;
	struct cli_credentials *anon_creds;
	struct smbcli_session *sessions[15];
	struct composite_context *composite_contexts[15];
	struct smbcli_tree *tree;
	struct smb_composite_sesssetup setup;
	struct smb_composite_sesssetup setups[15];
	union smb_open io;
	union smb_write wr;
	union smb_close cl;
	int fnum;
	const char *fname = BASEDIR "\\test.txt";
	uint8_t c = 1;
	int i;

	printf("TESTING SESSION HANDLING\n");

	if (!torture_setup_dir(cli, BASEDIR)) {
		return False;
	}

	printf("create a second security context on the same transport\n");
	session = smbcli_session_init(cli->transport, mem_ctx, False);

	setup.in.sesskey = cli->transport->negotiate.sesskey;
	setup.in.capabilities = cli->transport->negotiate.capabilities; /* ignored in secondary session setup, except by our libs, which care about the extended security bit */
	setup.in.workgroup = lp_workgroup();

	setup.in.credentials = cmdline_credentials;

	status = smb_composite_sesssetup(session, &setup);
	CHECK_STATUS(status, NT_STATUS_OK);
	
	session->vuid = setup.out.vuid;

	printf("create a third security context on the same transport, with vuid set\n");
	session2 = smbcli_session_init(cli->transport, mem_ctx, False);

	session2->vuid = session->vuid;
	setup.in.sesskey = cli->transport->negotiate.sesskey;
	setup.in.capabilities = cli->transport->negotiate.capabilities; /* ignored in secondary session setup, except by our libs, which care about the extended security bit */
	setup.in.workgroup = lp_workgroup();

	setup.in.credentials = cmdline_credentials;

	status = smb_composite_sesssetup(session2, &setup);
	CHECK_STATUS(status, NT_STATUS_OK);

	session2->vuid = setup.out.vuid;
	printf("vuid1=%d vuid2=%d vuid3=%d\n", cli->session->vuid, session->vuid, session2->vuid);
	
	if (cli->transport->negotiate.capabilities & CAP_EXTENDED_SECURITY) {
		/* Samba4 currently fails this - we need to determine if this insane behaviour is important */
		if (session2->vuid == session->vuid) {
			printf("server allows the user to re-use an existing vuid in session setup \n");
		}
	} else {
		CHECK_NOT_VALUE(session2->vuid, session->vuid);
	}
	talloc_free(session2);

	if (cli->transport->negotiate.capabilities & CAP_EXTENDED_SECURITY) {
		printf("create a fourth security context on the same transport, without extended security\n");
		session3 = smbcli_session_init(cli->transport, mem_ctx, False);

		session3->vuid = session->vuid;
		setup.in.sesskey = cli->transport->negotiate.sesskey;
		setup.in.capabilities &= ~CAP_EXTENDED_SECURITY; /* force a non extended security login (should fail) */
		setup.in.workgroup = lp_workgroup();
	
		setup.in.credentials = cmdline_credentials;
	

		status = smb_composite_sesssetup(session3, &setup);
		CHECK_STATUS(status, NT_STATUS_LOGON_FAILURE);

		printf("create a fouth anonymous security context on the same transport, without extended security\n");
		session4 = smbcli_session_init(cli->transport, mem_ctx, False);

		session4->vuid = session->vuid;
		setup.in.sesskey = cli->transport->negotiate.sesskey;
		setup.in.capabilities &= ~CAP_EXTENDED_SECURITY; /* force a non extended security login (should fail) */
		setup.in.workgroup = lp_workgroup();
		
		anon_creds = cli_credentials_init(mem_ctx);
		cli_credentials_set_conf(anon_creds);
		cli_credentials_set_anonymous(anon_creds);

		setup.in.credentials = anon_creds;
	
		status = smb_composite_sesssetup(session3, &setup);
		CHECK_STATUS(status, NT_STATUS_OK);

		talloc_free(session4);
	}
		
	printf("use the same tree as the existing connection\n");
	tree = smbcli_tree_init(session, mem_ctx, False);
	tree->tid = cli->tree->tid;

	printf("create a file using the new vuid\n");
	io.generic.level = RAW_OPEN_NTCREATEX;
	io.ntcreatex.in.root_fid = 0;
	io.ntcreatex.in.flags = 0;
	io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
	io.ntcreatex.in.create_options = 0;
	io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
	io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
	io.ntcreatex.in.alloc_size = 0;
	io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
	io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
	io.ntcreatex.in.security_flags = 0;
	io.ntcreatex.in.fname = fname;
	status = smb_raw_open(tree, mem_ctx, &io);
	CHECK_STATUS(status, NT_STATUS_OK);
	fnum = io.ntcreatex.out.file.fnum;

	printf("write using the old vuid\n");
	wr.generic.level = RAW_WRITE_WRITEX;
	wr.writex.in.file.fnum = fnum;
	wr.writex.in.offset = 0;
	wr.writex.in.wmode = 0;
	wr.writex.in.remaining = 0;
	wr.writex.in.count = 1;
	wr.writex.in.data = &c;

	status = smb_raw_write(cli->tree, &wr);
	CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);

	printf("write with the new vuid\n");
	status = smb_raw_write(tree, &wr);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VALUE(wr.writex.out.nwritten, 1);

	printf("logoff the new vuid\n");
	status = smb_raw_ulogoff(session);
	CHECK_STATUS(status, NT_STATUS_OK);

	printf("the new vuid should not now be accessible\n");
	status = smb_raw_write(tree, &wr);
	CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);

	printf("second logoff for the new vuid should fail\n");
	status = smb_raw_ulogoff(session);
	CHECK_STATUS(status, NT_STATUS_DOS(ERRSRV, ERRbaduid));
	talloc_free(session);

	printf("the fnum should have been auto-closed\n");
	cl.close.level = RAW_CLOSE_CLOSE;
	cl.close.in.file.fnum = fnum;
	cl.close.in.write_time = 0;
	status = smb_raw_close(cli->tree, &cl);
	CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);

	printf("create %d secondary security contexts on the same transport\n", 
	       (int)ARRAY_SIZE(sessions));
	for (i=0; i <ARRAY_SIZE(sessions); i++) {
		setups[i].in.sesskey = cli->transport->negotiate.sesskey;
		setups[i].in.capabilities = cli->transport->negotiate.capabilities; /* ignored in secondary session setup, except by our libs, which care about the extended security bit */
		setups[i].in.workgroup = lp_workgroup();
		
		setups[i].in.credentials = cmdline_credentials;

		sessions[i] = smbcli_session_init(cli->transport, mem_ctx, False);
		composite_contexts[i] = smb_composite_sesssetup_send(sessions[i], &setups[i]);

	}


	/* flush the queue */
	for (i=0; i < ARRAY_SIZE(sessions); i++) {
		event_loop_once(composite_contexts[0]->event_ctx);
	}

	printf("finishing %d secondary security contexts on the same transport\n", 
	       (int)ARRAY_SIZE(sessions));
	for (i=0; i< ARRAY_SIZE(sessions); i++) {
		status = smb_composite_sesssetup_recv(composite_contexts[i]);
		CHECK_STATUS(status, NT_STATUS_OK);
		sessions[i]->vuid = setups[i].out.vuid;
		printf("VUID: %d\n", sessions[i]->vuid);
		status = smb_raw_ulogoff(sessions[i]);
		CHECK_STATUS(status, NT_STATUS_OK);
	}


	talloc_free(tree);
	
done:
	return ret;
}
Exemplo n.º 9
0
/* Fill out the auth_session_info with a cli_credentials based on the
 * auth_session_info we were forwarded over named pipe forwarding.
 *
 * NOTE: The stucture members of session_info_transport are stolen
 * with talloc_move() into auth_session_info for long term use
 */
struct auth_session_info *auth_session_info_from_transport(TALLOC_CTX *mem_ctx,
        struct auth_session_info_transport *session_info_transport,
        struct loadparm_context *lp_ctx,
        const char **reason)
{
    struct auth_session_info *session_info;
    session_info = talloc_steal(mem_ctx, session_info_transport->session_info);

    if (session_info_transport->exported_gssapi_credentials.length) {
        struct cli_credentials *creds;
        OM_uint32 minor_status;
        gss_buffer_desc cred_token;
        gss_cred_id_t cred_handle;
        const char *error_string;
        int ret;

        DEBUG(10, ("Delegated credentials supplied by client\n"));

        cred_token.value = session_info_transport->exported_gssapi_credentials.data;
        cred_token.length = session_info_transport->exported_gssapi_credentials.length;

        ret = gss_import_cred(&minor_status,
                              &cred_token,
                              &cred_handle);
        if (ret != GSS_S_COMPLETE) {
            *reason = "Internal error in gss_import_cred()";
            return NULL;
        }

        creds = cli_credentials_init(session_info);
        if (!creds) {
            *reason = "Out of memory in cli_credentials_init()";
            return NULL;
        }
        session_info->credentials = creds;

        cli_credentials_set_conf(creds, lp_ctx);
        /* Just so we don't segfault trying to get at a username */
        cli_credentials_set_anonymous(creds);

        ret = cli_credentials_set_client_gss_creds(creds,
                lp_ctx,
                cred_handle,
                CRED_SPECIFIED,
                &error_string);
        if (ret) {
            *reason = talloc_asprintf(mem_ctx,
                                      "Failed to set pipe forwarded"
                                      "creds: %s\n", error_string);
            return NULL;
        }

        /* This credential handle isn't useful for password
         * authentication, so ensure nobody tries to do that */
        cli_credentials_set_kerberos_state(creds,
                                           CRED_MUST_USE_KERBEROS);

    }

    return session_info;
}
Exemplo n.º 10
0
static int ejs_cli_ssetup(MprVarHandle eid, int argc, MprVar **argv)
{
	struct smbcli_transport *transport;
	struct smbcli_session *session;
	struct smb_composite_sesssetup setup;
	struct cli_credentials *creds;
	NTSTATUS status;
	int result = -1;

	/* Argument parsing */

	if (argc < 1 || argc > 4) {
		ejsSetErrorMsg(eid, "session_setup invalid arguments");
		return -1;
	}

	if (!mprVarIsPtr(argv[0]->type)) {
		ejsSetErrorMsg(eid, "first arg is not a connect handle");
		return -1;
	}

	transport = argv[0]->ptr;
	creds = cli_credentials_init(transport);
	cli_credentials_set_conf(creds);

	if (argc == 4) {

		/* DOMAIN, USERNAME, PASSWORD form */

		if (!mprVarIsString(argv[1]->type)) {
			ejsSetErrorMsg(eid, "arg 1 must be a string");
			goto done;
		}

		cli_credentials_set_domain(creds, argv[1]->string, 
					   CRED_SPECIFIED);

		if (!mprVarIsString(argv[2]->type)) {
			ejsSetErrorMsg(eid, "arg 2 must be a string");
			goto done;
		}

		cli_credentials_set_username(creds, argv[2]->string, 
					     CRED_SPECIFIED);

		if (!mprVarIsString(argv[3]->type)) {
			ejsSetErrorMsg(eid, "arg 3 must be a string");
			goto done;
		}

		cli_credentials_set_password(creds, argv[3]->string,
					     CRED_SPECIFIED);

	} else if (argc == 3) {

		/* USERNAME, PASSWORD form */

		if (!mprVarIsString(argv[1]->type)) {
			ejsSetErrorMsg(eid, "arg1 must be a string");
			goto done;
		}

		cli_credentials_set_username(creds, argv[1]->string,
					     CRED_SPECIFIED);

		if (!mprVarIsString(argv[2]->type)) {

			ejsSetErrorMsg(eid, "arg2 must be a string");
			goto done;
		}

		cli_credentials_set_password(creds, argv[2]->string,
					     CRED_SPECIFIED);

	} else if (argc == 2) {

		/* DOMAIN/USERNAME%PASSWORD form */

		cli_credentials_parse_string(creds, argv[1]->string,
					     CRED_SPECIFIED);

	} else {

		/* Anonymous connection */

		cli_credentials_set_anonymous(creds);
	}

	/* Do session setup */

	session = smbcli_session_init(transport, transport, False);

	if (!session) {
		ejsSetErrorMsg(eid, "session init failed");
		return -1;
	}

	setup.in.sesskey = transport->negotiate.sesskey;
	setup.in.capabilities = transport->negotiate.capabilities;
	setup.in.credentials = creds;
	setup.in.workgroup = lp_workgroup();

	status = smb_composite_sesssetup(session, &setup);

	if (!NT_STATUS_IS_OK(status)) {
		ejsSetErrorMsg(eid, "session_setup: %s", nt_errstr(status));
		return -1;
	}

	session->vuid = setup.out.vuid;	

	/* Return a session object */

	mpr_Return(eid, mprCreatePtrVar(session));

	result = 0;

 done:
	talloc_free(creds);
	return result;
}
Exemplo n.º 11
0
static int set_ldap_credentials(struct ldb_context *ldb, bool use_external)
{
	const char *secrets_ldb_path, *sam_ldb_path;
	char *private_dir, *p, *error_string;
	struct ldb_context *secrets_ldb;
	struct cli_credentials *cred;
	struct loadparm_context *lp_ctx = ldb_get_opaque(ldb, "loadparm");
	TALLOC_CTX *tmp_ctx = talloc_new(ldb);

	if (!tmp_ctx) {
		return ldb_oom(ldb);
	}

	cred = cli_credentials_init(ldb);
	if (!cred) {
		talloc_free(tmp_ctx);
		return ldb_oom(ldb);
	}
	cli_credentials_set_anonymous(cred);
	if (use_external) {
		cli_credentials_set_forced_sasl_mech(cred, "EXTERNAL");
	} else {
		cli_credentials_set_forced_sasl_mech(cred, "DIGEST-MD5");

		/*
		 * We don't want to use krb5 to talk to our samdb - recursion
		 * here would be bad, and this account isn't in the KDC
		 * anyway
		 */
		cli_credentials_set_kerberos_state(cred, CRED_DONT_USE_KERBEROS);

		/*
		 * Work out where *our* secrets.ldb is.  It must be in
		 * the same directory as sam.ldb
		 */
		sam_ldb_path = (const char *)ldb_get_opaque(ldb, "ldb_url");
		if (!sam_ldb_path) {
			talloc_free(tmp_ctx);
			return ldb_operr(ldb);
		}
		if (strncmp("tdb://", sam_ldb_path, 6) == 0) {
			sam_ldb_path += 6;
		}
		private_dir = talloc_strdup(tmp_ctx, sam_ldb_path);
		p = strrchr(private_dir, '/');
		if (p) {
			*p = '\0';
		} else {
			private_dir = talloc_strdup(tmp_ctx, ".");
		}

		secrets_ldb_path = talloc_asprintf(private_dir, "tdb://%s/secrets.ldb",
						   private_dir);

		if (!secrets_ldb_path) {
			talloc_free(tmp_ctx);
			return ldb_oom(ldb);
		}

		/*
		 * Now that we have found the location, connect to
		 * secrets.ldb so we can read the SamDB Credentials
		 * record
		 */
		secrets_ldb = ldb_wrap_connect(tmp_ctx, NULL, lp_ctx, secrets_ldb_path,
					       NULL, NULL, 0);

		if (!NT_STATUS_IS_OK(cli_credentials_set_secrets(cred, NULL, secrets_ldb, NULL,
								 SECRETS_LDAP_FILTER, &error_string))) {
			ldb_asprintf_errstring(ldb, "Failed to read LDAP backend password from %s", secrets_ldb_path);
			talloc_free(tmp_ctx);
			return LDB_ERR_STRONG_AUTH_REQUIRED;
		}
	}

	/*
	 * Finally overwrite any supplied credentials with
	 * these ones, as only secrets.ldb contains the magic
	 * credentials to talk on the ldapi socket
	 */
	if (ldb_set_opaque(ldb, "credentials", cred)) {
		talloc_free(tmp_ctx);
		return ldb_operr(ldb);
	}
	talloc_free(tmp_ctx);
	return LDB_SUCCESS;
}
Exemplo n.º 12
0
/* Get some basic (and authorization) information about the user on
 * this session.  This uses either the PAC (if present) or a local
 * database lookup */
static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_security,
					   TALLOC_CTX *mem_ctx,
					   struct auth_session_info **_session_info) 
{
	NTSTATUS nt_status;
	TALLOC_CTX *tmp_ctx;
	struct gensec_gssapi_state *gensec_gssapi_state
		= talloc_get_type(gensec_security->private_data, struct gensec_gssapi_state);
	struct auth_session_info *session_info = NULL;
	OM_uint32 maj_stat, min_stat;
	DATA_BLOB pac_blob, *pac_blob_ptr = NULL;

	gss_buffer_desc name_token;
	char *principal_string;
	
	tmp_ctx = talloc_named(mem_ctx, 0, "gensec_gssapi_session_info context");
	NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);

	maj_stat = gss_display_name (&min_stat,
				     gensec_gssapi_state->client_name,
				     &name_token,
				     NULL);
	if (GSS_ERROR(maj_stat)) {
		DEBUG(1, ("GSS display_name failed: %s\n",
			  gssapi_error_string(tmp_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid)));
		talloc_free(tmp_ctx);
		return NT_STATUS_FOOBAR;
	}

	principal_string = talloc_strndup(tmp_ctx,
					  (const char *)name_token.value,
					  name_token.length);

	gss_release_buffer(&min_stat, &name_token);

	if (!principal_string) {
		talloc_free(tmp_ctx);
		return NT_STATUS_NO_MEMORY;
	}

	nt_status = gssapi_obtain_pac_blob(tmp_ctx,  gensec_gssapi_state->gssapi_context,
					   gensec_gssapi_state->client_name,
					   &pac_blob);
	
	/* IF we have the PAC - otherwise we need to get this
	 * data from elsewere - local ldb, or (TODO) lookup of some
	 * kind... 
	 */
	if (NT_STATUS_IS_OK(nt_status)) {
		pac_blob_ptr = &pac_blob;
	}
	nt_status = gensec_generate_session_info_pac(tmp_ctx,
						     gensec_security,
						     gensec_gssapi_state->smb_krb5_context,
						     pac_blob_ptr, principal_string,
						     gensec_get_remote_address(gensec_security),
						     &session_info);
	if (!NT_STATUS_IS_OK(nt_status)) {
		talloc_free(tmp_ctx);
		return nt_status;
	}

	nt_status = gensec_gssapi_session_key(gensec_security, session_info, &session_info->session_key);
	if (!NT_STATUS_IS_OK(nt_status)) {
		talloc_free(tmp_ctx);
		return nt_status;
	}

	if (gensec_gssapi_state->gss_got_flags & GSS_C_DELEG_FLAG &&
	    gensec_gssapi_state->delegated_cred_handle != GSS_C_NO_CREDENTIAL) {
		krb5_error_code ret;
		const char *error_string;

		DEBUG(10, ("gensec_gssapi: delegated credentials supplied by client\n"));
		session_info->credentials = cli_credentials_init(session_info);
		if (!session_info->credentials) {
			talloc_free(tmp_ctx);
			return NT_STATUS_NO_MEMORY;
		}

		cli_credentials_set_conf(session_info->credentials, gensec_security->settings->lp_ctx);
		/* Just so we don't segfault trying to get at a username */
		cli_credentials_set_anonymous(session_info->credentials);
		
		ret = cli_credentials_set_client_gss_creds(session_info->credentials, 
							   gensec_security->settings->lp_ctx,
							   gensec_gssapi_state->delegated_cred_handle,
							   CRED_SPECIFIED, &error_string);
		if (ret) {
			talloc_free(tmp_ctx);
			DEBUG(2,("Failed to get gss creds: %s\n", error_string));
			return NT_STATUS_NO_MEMORY;
		}
		
		/* This credential handle isn't useful for password authentication, so ensure nobody tries to do that */
		cli_credentials_set_kerberos_state(session_info->credentials, CRED_MUST_USE_KERBEROS);

		/* It has been taken from this place... */
		gensec_gssapi_state->delegated_cred_handle = GSS_C_NO_CREDENTIAL;
	} else {
		DEBUG(10, ("gensec_gssapi: NO delegated credentials supplied by client\n"));
	}

	*_session_info = talloc_steal(mem_ctx, session_info);
	talloc_free(tmp_ctx);

	return NT_STATUS_OK;
}
Exemplo n.º 13
0
static void gtk_get_credentials(struct cli_credentials *credentials)
{
	const char *ret;
	GtkWidget *dialog;
	GtkWidget *label;
	GtkWidget *table;
	GtkWidget *entry_username;
	GtkWidget *entry_password;
	GtkWidget *dialog_action_area1;
	GtkWidget *cancelbutton1;
	GtkWidget *okbutton1;
	GtkWidget *anonymous;
	const char *username;

	dialog = gtk_dialog_new ();
	gtk_window_set_title (GTK_WINDOW (dialog), "Credentials");
	gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
	gtk_window_set_type_hint (GTK_WINDOW (dialog), GDK_WINDOW_TYPE_HINT_DIALOG);

	table = gtk_table_new(4, 2, FALSE);
	gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), table);

	label = gtk_label_new ("Username:"******"Password:"******"_Anonymous");
	gtk_table_attach(GTK_TABLE(table),anonymous,0,2,4,5,GTK_FILL,0,0,0);

	dialog_action_area1 = GTK_DIALOG (dialog)->action_area;
	gtk_button_box_set_layout (GTK_BUTTON_BOX (dialog_action_area1), GTK_BUTTONBOX_END);

	cancelbutton1 = gtk_button_new_from_stock ("gtk-cancel");
	gtk_dialog_add_action_widget (GTK_DIALOG (dialog), cancelbutton1, GTK_RESPONSE_CANCEL);
	GTK_WIDGET_SET_FLAGS (cancelbutton1, GTK_CAN_DEFAULT);

	okbutton1 = gtk_button_new_from_stock ("gtk-ok");
	gtk_dialog_add_action_widget (GTK_DIALOG (dialog), okbutton1, GTK_RESPONSE_OK);
	GTK_WIDGET_SET_FLAGS (okbutton1, GTK_CAN_DEFAULT);

	gtk_widget_show_all (dialog);

    switch (gtk_dialog_run (GTK_DIALOG (dialog))) {
	case GTK_RESPONSE_OK:
		cli_credentials_parse_string(credentials, gtk_entry_get_text(GTK_ENTRY(entry_username)), CRED_CALLBACK_RESULT);
		cli_credentials_set_password(credentials, gtk_entry_get_text(GTK_ENTRY(entry_password)), CRED_CALLBACK_RESULT);

		if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(anonymous))) {
			cli_credentials_set_anonymous(credentials);
		}
		break;
	default:
		ret = NULL;
		break;
	}

	gtk_widget_destroy (dialog);
}
Exemplo n.º 14
0
static PyObject *py_creds_set_anonymous(PyObject *self, PyObject *unused)
{
	cli_credentials_set_anonymous(PyCredentials_AsCliCredentials(self));
	Py_RETURN_NONE;
}
Exemplo n.º 15
0
/**
 * Fill in credentials for the machine trust account, from the
 * secrets.ldb or passed in handle to secrets.tdb (perhaps in CTDB).
 *
 * This version is used in parts of the code that can link in the
 * CTDB dbwrap backend, by passing down the already open handle.
 *
 * @param cred Credentials structure to fill in
 * @param db_ctx dbwrap context for secrets.tdb
 * @retval NTSTATUS error detailing any failure
 */
_PUBLIC_ NTSTATUS cli_credentials_set_machine_account_db_ctx(struct cli_credentials *cred,
							     struct loadparm_context *lp_ctx,
							     struct db_context *db_ctx)
{
	NTSTATUS status;
	char *filter;
	char *error_string = NULL;
	const char *domain;
	bool secrets_tdb_password_more_recent;
	time_t secrets_tdb_lct = 0;
	char *secrets_tdb_password = NULL;
	char *secrets_tdb_old_password = NULL;
	uint32_t secrets_tdb_secure_channel_type = SEC_CHAN_NULL;
	char *keystr;
	char *keystr_upper = NULL;
	TALLOC_CTX *tmp_ctx = talloc_named(cred, 0, "cli_credentials_set_secrets from ldb");
	if (!tmp_ctx) {
		return NT_STATUS_NO_MEMORY;
	}

	/* Bleh, nasty recursion issues: We are setting a machine
	 * account here, so we don't want the 'pending' flag around
	 * any more */
	cred->machine_account_pending = false;

	/* We have to do this, as the fallback in
	 * cli_credentials_set_secrets is to run as anonymous, so the domain is wiped */
	domain = cli_credentials_get_domain(cred);

	if (db_ctx) {
		TDB_DATA dbuf;
		keystr = talloc_asprintf(tmp_ctx, "%s/%s",
					 SECRETS_MACHINE_LAST_CHANGE_TIME,
					 domain);
		keystr_upper = strupper_talloc(tmp_ctx, keystr);
		status = dbwrap_fetch(db_ctx, tmp_ctx, string_tdb_data(keystr_upper),
				      &dbuf);
		if (NT_STATUS_IS_OK(status) && dbuf.dsize == 4) {
			secrets_tdb_lct = IVAL(dbuf.dptr,0);
		}

		keystr = talloc_asprintf(tmp_ctx, "%s/%s",
					 SECRETS_MACHINE_PASSWORD,
					 domain);
		keystr_upper = strupper_talloc(tmp_ctx, keystr);
		status = dbwrap_fetch(db_ctx, tmp_ctx, string_tdb_data(keystr_upper),
				      &dbuf);
		if (NT_STATUS_IS_OK(status)) {
			secrets_tdb_password = (char *)dbuf.dptr;
		}

		keystr = talloc_asprintf(tmp_ctx, "%s/%s",
					 SECRETS_MACHINE_PASSWORD_PREV,
					 domain);
		keystr_upper = strupper_talloc(tmp_ctx, keystr);
		status = dbwrap_fetch(db_ctx, tmp_ctx, string_tdb_data(keystr_upper),
				      &dbuf);
		if (NT_STATUS_IS_OK(status)) {
			secrets_tdb_old_password = (char *)dbuf.dptr;
		}

		keystr = talloc_asprintf(tmp_ctx, "%s/%s",
					 SECRETS_MACHINE_SEC_CHANNEL_TYPE,
					 domain);
		keystr_upper = strupper_talloc(tmp_ctx, keystr);
		status = dbwrap_fetch(db_ctx, tmp_ctx, string_tdb_data(keystr_upper),
				      &dbuf);
		if (NT_STATUS_IS_OK(status) && dbuf.dsize == 4) {
			secrets_tdb_secure_channel_type = IVAL(dbuf.dptr,0);
		}
	}

	filter = talloc_asprintf(cred, SECRETS_PRIMARY_DOMAIN_FILTER, 
				 domain);
	status = cli_credentials_set_secrets_lct(cred, lp_ctx, NULL,
						 SECRETS_PRIMARY_DOMAIN_DN,
						 filter, secrets_tdb_lct, secrets_tdb_password, &error_string);
	if (secrets_tdb_password == NULL) {
		secrets_tdb_password_more_recent = false;
	} else if (NT_STATUS_EQUAL(NT_STATUS_CANT_ACCESS_DOMAIN_INFO, status)
	    || NT_STATUS_EQUAL(NT_STATUS_NOT_FOUND, status)) {
		secrets_tdb_password_more_recent = true;
	} else if (secrets_tdb_lct > cli_credentials_get_password_last_changed_time(cred)) {
		secrets_tdb_password_more_recent = true;
	} else if (secrets_tdb_lct == cli_credentials_get_password_last_changed_time(cred)) {
		secrets_tdb_password_more_recent = strcmp(secrets_tdb_password, cli_credentials_get_password(cred)) != 0;
	} else {
		secrets_tdb_password_more_recent = false;
	}

	if (secrets_tdb_password_more_recent) {
		char *machine_account = talloc_asprintf(tmp_ctx, "%s$", lpcfg_netbios_name(lp_ctx));
		cli_credentials_set_password(cred, secrets_tdb_password, CRED_SPECIFIED);
		cli_credentials_set_old_password(cred, secrets_tdb_old_password, CRED_SPECIFIED);
		cli_credentials_set_domain(cred, domain, CRED_SPECIFIED);
		if (strequal(domain, lpcfg_workgroup(lp_ctx))) {
			cli_credentials_set_realm(cred, lpcfg_realm(lp_ctx), CRED_SPECIFIED);
		}
		cli_credentials_set_username(cred, machine_account, CRED_SPECIFIED);
		cli_credentials_set_password_last_changed_time(cred, secrets_tdb_lct);
		cli_credentials_set_secure_channel_type(cred, secrets_tdb_secure_channel_type);
		status = NT_STATUS_OK;
	} else if (!NT_STATUS_IS_OK(status)) {
		if (db_ctx) {
			error_string
				= talloc_asprintf(cred,
						  "Failed to fetch machine account password for %s from both "
						  "secrets.ldb (%s) and from %s",
						  domain,
						  error_string == NULL ? "error" : error_string,
						  dbwrap_name(db_ctx));
		} else {
			char *secrets_tdb_path;

			secrets_tdb_path = lpcfg_private_db_path(tmp_ctx,
								 lp_ctx,
								 "secrets");
			if (secrets_tdb_path == NULL) {
				return NT_STATUS_NO_MEMORY;
			}

			error_string = talloc_asprintf(cred,
						       "Failed to fetch machine account password from "
						       "secrets.ldb: %s and failed to open %s",
						       error_string == NULL ? "error" : error_string,
						       secrets_tdb_path);
		}
		DEBUG(1, ("Could not find machine account in secrets database: %s: %s\n",
			  error_string == NULL ? "error" : error_string,
			  nt_errstr(status)));
		/* set anonymous as the fallback, if the machine account won't work */
		cli_credentials_set_anonymous(cred);
	}

	TALLOC_FREE(tmp_ctx);
	return status;
}
Exemplo n.º 16
0
static PyObject *py_creds_set_anonymous(pytalloc_Object *self)
{
	cli_credentials_set_anonymous(PyCredentials_AsCliCredentials(self));
	Py_RETURN_NONE;
}