Exemple #1
0
/** 
 * The challenge from the target server, when operating in security=server
 **/
static NTSTATUS server_get_challenge(struct auth_method_context *ctx, TALLOC_CTX *mem_ctx, uint8_t chal[8])
{
	struct smb_composite_connect io;
	struct smbcli_options smb_options;
	const char **host_list;
	NTSTATUS status;

	/* Make a connection to the target server, found by 'password server' in smb.conf */
	
	lp_smbcli_options(ctx->auth_ctx->lp_ctx, &smb_options);

	/* Make a negprot, WITHOUT SPNEGO, so we get a challenge nice an easy */
	io.in.options.use_spnego = false;

	/* Hope we don't get * (the default), as this won't work... */
	host_list = lp_passwordserver(ctx->auth_ctx->lp_ctx); 
	if (!host_list) {
		return NT_STATUS_INTERNAL_ERROR;
	}
	io.in.dest_host = host_list[0];
	if (strequal(io.in.dest_host, "*")) {
		return NT_STATUS_INTERNAL_ERROR;
	}
	io.in.dest_ports = lp_smb_ports(ctx->auth_ctx->lp_ctx); 
	io.in.socket_options = lp_socket_options(ctx->auth_ctx->lp_ctx);
	io.in.gensec_settings = lp_gensec_settings(mem_ctx, ctx->auth_ctx->lp_ctx);

	io.in.called_name = strupper_talloc(mem_ctx, io.in.dest_host);

	/* We don't want to get as far as the session setup */
	io.in.credentials = cli_credentials_init_anon(mem_ctx);
	cli_credentials_set_workstation(io.in.credentials,
					lp_netbios_name(ctx->auth_ctx->lp_ctx),
					CRED_SPECIFIED);

	io.in.service = NULL;

	io.in.workgroup = ""; /* only used with SPNEGO, disabled above */

	io.in.options = smb_options;
	
	io.in.iconv_convenience = lp_iconv_convenience(ctx->auth_ctx->lp_ctx);
	lp_smbcli_session_options(ctx->auth_ctx->lp_ctx, &io.in.session_options);

	status = smb_composite_connect(&io, mem_ctx, lp_resolve_context(ctx->auth_ctx->lp_ctx),
				       ctx->auth_ctx->event_ctx);
	NT_STATUS_NOT_OK_RETURN(status);

	if (io.out.tree->session->transport->negotiate.secblob.length != 8) {
		return NT_STATUS_INTERNAL_ERROR;
	}
	memcpy(chal, io.out.tree->session->transport->negotiate.secblob.data, 8);
	ctx->private_data = talloc_steal(ctx, io.out.tree->session);
	return NT_STATUS_OK;
}
Exemple #2
0
static
NTSTATUS schannel_store_session_key_tdb(struct tdb_wrap *tdb_sc,
					TALLOC_CTX *mem_ctx,
					struct netlogon_creds_CredentialState *creds)
{
	enum ndr_err_code ndr_err;
	DATA_BLOB blob;
	TDB_DATA value;
	int ret;
	char *keystr;
	char *name_upper;

	name_upper = strupper_talloc(mem_ctx, creds->computer_name);
	if (!name_upper) {
		return NT_STATUS_NO_MEMORY;
	}

	keystr = talloc_asprintf(mem_ctx, "%s/%s",
				 SECRETS_SCHANNEL_STATE, name_upper);
	TALLOC_FREE(name_upper);
	if (!keystr) {
		return NT_STATUS_NO_MEMORY;
	}

	ndr_err = ndr_push_struct_blob(&blob, mem_ctx, creds,
			(ndr_push_flags_fn_t)ndr_push_netlogon_creds_CredentialState);
	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
		talloc_free(keystr);
		return ndr_map_error2ntstatus(ndr_err);
	}

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

	ret = tdb_store_bystring(tdb_sc->tdb, keystr, value, TDB_REPLACE);
	if (ret != TDB_SUCCESS) {
		DEBUG(0,("Unable to add %s to session key db - %s\n",
			 keystr, tdb_errorstr_compat(tdb_sc->tdb)));
		talloc_free(keystr);
		return NT_STATUS_INTERNAL_DB_CORRUPTION;
	}

	DEBUG(3,("schannel_store_session_key_tdb: stored schannel info with key %s\n",
		keystr));

	if (DEBUGLEVEL >= 10) {
		NDR_PRINT_DEBUG(netlogon_creds_CredentialState, creds);
	}

	talloc_free(keystr);

	return NT_STATUS_OK;
}
Exemple #3
0
/**
 * Set the realm for this credentials context, and force it to
 * uppercase for the sainity of our local kerberos libraries 
 */
_PUBLIC_ bool cli_credentials_set_realm(struct cli_credentials *cred, 
			       const char *val, 
			       enum credentials_obtained obtained)
{
	if (obtained >= cred->realm_obtained) {
		cred->realm = strupper_talloc(cred, val);
		cred->realm_obtained = obtained;
		cli_credentials_invalidate_ccache(cred, cred->realm_obtained);
		return true;
	}

	return false;
}
static int ejs_tree_connect(MprVarHandle eid, int argc, char **argv)
{
	struct cli_credentials *creds;
	struct smb_composite_connect io;
	struct smbcli_tree *tree;
	char *hostname, *sharename;
	NTSTATUS result;
	TALLOC_CTX *mem_ctx;

	if (argc != 2) {
		ejsSetErrorMsg(eid, "tree_connect(): invalid number of args");
		return -1;
	}

	/* Set up host, share destination */

	mem_ctx = talloc_new(mprMemCtx());
	smbcli_parse_unc(argv[0], mem_ctx, &hostname, &sharename);

	/* Set up credentials */

	creds = cli_credentials_init(NULL);
	cli_credentials_set_conf(creds);
	cli_credentials_parse_string(creds, argv[1], CRED_SPECIFIED);

	/* Do connect */

	io.in.dest_host              = hostname;
	io.in.port                   = 0;
	io.in.called_name            = strupper_talloc(mem_ctx, hostname);
	io.in.service                = sharename;
	io.in.service_type           = "?????";
	io.in.credentials            = creds;
	io.in.fallback_to_anonymous  = False;
	io.in.workgroup              = lp_workgroup();

	result = smb_composite_connect(&io, mem_ctx, NULL);
	tree = io.out.tree;

	talloc_free(mem_ctx);

	if (!NT_STATUS_IS_OK(result)) {
		mpr_Return(eid, mprNTSTATUS(result));
		return 0;
	}

	mpr_Return(eid, mprCreatePtrVar(tree));

	return 0;
}
Exemple #5
0
bool torture_nbt_get_name(struct torture_context *tctx, 
			  struct nbt_name *name, 
			  const char **address)
{
	make_nbt_name_server(name, strupper_talloc(tctx, 
			     torture_setting_string(tctx, "host", NULL)));

	/* do an initial name resolution to find its IP */
	torture_assert_ntstatus_ok(tctx, 
				   resolve_name_ex(lpcfg_resolve_context(tctx->lp_ctx),
						   0, 0,
						   name, tctx, address, tctx->ev),
				   talloc_asprintf(tctx, 
						   "Failed to resolve %s", name->name));
	
	return true;
}
Exemple #6
0
_PUBLIC_ bool cli_credentials_set_domain(struct cli_credentials *cred, 
				const char *val, 
				enum credentials_obtained obtained)
{
	if (obtained >= cred->domain_obtained) {
		/* it is important that the domain be in upper case,
		 * particularly for the sensitive NTLMv2
		 * calculations */
		cred->domain = strupper_talloc(cred, val);
		cred->domain_obtained = obtained;
		/* setting domain does not mean we have to invalidate ccache 
		 * because domain in not used for Kerberos operations.
		 * If ccache invalidation is required, one will anyway specify
		 * a password to kinit, and that will force invalidation of the ccache
		 */
		return true;
	}

	return false;
}
Exemple #7
0
static bool torture_winbind_struct_netbios_name(struct torture_context *torture)
{
	struct winbindd_response rep;
	const char *expected;

	ZERO_STRUCT(rep);

	torture_comment(torture, "Running WINBINDD_NETBIOS_NAME (struct based)\n");

	DO_STRUCT_REQ_REP(WINBINDD_NETBIOS_NAME, NULL, &rep);

	expected = torture_setting_string(torture,
					  "winbindd_netbios_name",
					  lpcfg_netbios_name(torture->lp_ctx));
	expected = strupper_talloc(torture, expected);

	torture_assert_str_equal(torture,
				 rep.data.netbios_name, expected,
				 "winbindd's netbios name doesn't match");

	return true;
}
Exemple #8
0
static int fix_dn(struct ldb_dn *dn) 
{
	int i, ret;
	char *upper_rdn_attr;

	for (i=0; i < ldb_dn_get_comp_num(dn); i++) {
		/* We need the attribute name in upper case */
		upper_rdn_attr = strupper_talloc(dn,
						 ldb_dn_get_component_name(dn, i));
		if (!upper_rdn_attr) {
			return LDB_ERR_OPERATIONS_ERROR;
		}
		
		/* And replace it with CN=foo (we need the attribute in upper case */
		ret = ldb_dn_set_component(dn, i, upper_rdn_attr,
					   *ldb_dn_get_component_val(dn, i));
		talloc_free(upper_rdn_attr);
		if (ret != LDB_SUCCESS) {
			return ret;
		}
	}
	return LDB_SUCCESS;
}
Exemple #9
0
bool E_deshash(const char *passwd, uint8_t p16[16])
{
	bool ret;
	uint8_t dospwd[14];
	TALLOC_CTX *frame = talloc_stackframe();

	size_t converted_size;

	char *tmpbuf;

	ZERO_STRUCT(dospwd);

	tmpbuf = strupper_talloc(frame, passwd);
	if (tmpbuf == NULL) {
		/* Too many callers don't check this result, we need to fill in the buffer with something */
		strlcpy((char *)dospwd, passwd ? passwd : "", sizeof(dospwd));
		E_P16(dospwd, p16);
		talloc_free(frame);
		return false;
	}

	ZERO_STRUCT(dospwd);

	ret = convert_string_error(CH_UNIX, CH_DOS, tmpbuf, strlen(tmpbuf), dospwd, sizeof(dospwd), &converted_size);
	talloc_free(frame);

	/* Only the first 14 chars are considered, password need not
	 * be null terminated.  We do this in the error and success
	 * case to avoid returning a fixed 'password' buffer, but
	 * callers should not use it when E_deshash returns false */

	E_P16((const uint8_t *)dospwd, p16);

	ZERO_STRUCT(dospwd);

	return ret;
}
Exemple #10
0
static WERROR cmd_predef(struct regshell_context *ctx, int argc, char **argv)
{
	struct registry_key *ret = NULL;
	if (argc < 2) {
		fprintf(stderr, "Usage: predef predefined-key-name\n");
	} else if (!ctx) {
		fprintf(stderr, "No full registry loaded, no predefined keys defined\n");
	} else {
		WERROR error = reg_get_predefined_key_by_name(ctx->registry,
							      argv[1], &ret);

		if (!W_ERROR_IS_OK(error)) {
			fprintf(stderr, "Error opening predefined key %s: %s\n",
				argv[1], win_errstr(error));
			return error;
		}

		ctx->predef = strupper_talloc(ctx, argv[1]);
		ctx->current = ret;
		ctx->root = ret;
	}

	return WERR_OK;
}
/**
 * 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;
}
Exemple #12
0
static ADS_STATUS ads_guess_target(ADS_STRUCT *ads,
				   char **service,
				   char **hostname,
				   char **principal)
{
	ADS_STATUS status = ADS_ERROR(LDAP_NO_MEMORY);
	char *princ = NULL;
	TALLOC_CTX *frame;
	char *server = NULL;
	char *realm = NULL;
	int rc;

	frame = talloc_stackframe();
	if (frame == NULL) {
		return ADS_ERROR(LDAP_NO_MEMORY);
	}

	if (ads->server.realm && ads->server.ldap_server) {
		server = strlower_talloc(frame, ads->server.ldap_server);
		if (server == NULL) {
			goto out;
		}

		realm = strupper_talloc(frame, ads->server.realm);
		if (realm == NULL) {
			goto out;
		}

		/*
		 * If we got a name which is bigger than a NetBIOS name,
		 * but isn't a FQDN, create one.
		 */
		if (strlen(server) > 15 && strstr(server, ".") == NULL) {
			char *dnsdomain;

			dnsdomain = strlower_talloc(frame, ads->server.realm);
			if (dnsdomain == NULL) {
				goto out;
			}

			server = talloc_asprintf(frame,
						 "%s.%s",
						 server, dnsdomain);
			if (server == NULL) {
				goto out;
			}
		}
	} else if (ads->config.realm && ads->config.ldap_server_name) {
		server = strlower_talloc(frame, ads->config.ldap_server_name);
		if (server == NULL) {
			goto out;
		}

		realm = strupper_talloc(frame, ads->config.realm);
		if (realm == NULL) {
			goto out;
		}

		/*
		 * If we got a name which is bigger than a NetBIOS name,
		 * but isn't a FQDN, create one.
		 */
		if (strlen(server) > 15 && strstr(server, ".") == NULL) {
			char *dnsdomain;

			dnsdomain = strlower_talloc(frame, ads->server.realm);
			if (dnsdomain == NULL) {
				goto out;
			}

			server = talloc_asprintf(frame,
						 "%s.%s",
						 server, dnsdomain);
			if (server == NULL) {
				goto out;
			}
		}
	}

	if (server == NULL || realm == NULL) {
		goto out;
	}

	*service = SMB_STRDUP("ldap");
	if (*service == NULL) {
		status = ADS_ERROR(LDAP_PARAM_ERROR);
		goto out;
	}
	*hostname = SMB_STRDUP(server);
	if (*hostname == NULL) {
		SAFE_FREE(*service);
		status = ADS_ERROR(LDAP_PARAM_ERROR);
		goto out;
	}
	rc = asprintf(&princ, "ldap/%s@%s", server, realm);
	if (rc == -1 || princ == NULL) {
		SAFE_FREE(*service);
		SAFE_FREE(*hostname);
		status = ADS_ERROR(LDAP_PARAM_ERROR);
		goto out;
	}

	*principal = princ;

	status = ADS_SUCCESS;
out:
	TALLOC_FREE(frame);
	return status;
}
Exemple #13
0
static int smb_krb5_create_salt_principal(TALLOC_CTX *mem_ctx,
					  const char *samAccountName,
					  const char *realm,
					  const char **salt_principal,
					  const char **error_string)
{
	char *machine_username;
	bool is_machine_account = false;
	char *upper_realm;
	TALLOC_CTX *tmp_ctx;
	int rc = -1;

	if (samAccountName == NULL) {
		*error_string = "Cannot determine salt principal, no "
				"saltPrincipal or samAccountName specified";
		return rc;
	}

	if (realm == NULL) {
		*error_string = "Cannot make principal without a realm";
		return rc;
	}

	tmp_ctx = talloc_new(mem_ctx);
	if (tmp_ctx == NULL) {
		*error_string = "Cannot allocate talloc context";
		return rc;
	}

	upper_realm = strupper_talloc(tmp_ctx, realm);
	if (upper_realm == NULL) {
		*error_string = "Cannot allocate to upper case realm";
		goto out;
	}

	machine_username = strlower_talloc(tmp_ctx, samAccountName);
	if (!machine_username) {
		*error_string = "Cannot duplicate samAccountName";
		goto out;
	}

	if (machine_username[strlen(machine_username) - 1] == '$') {
		machine_username[strlen(machine_username) - 1] = '\0';
		is_machine_account = true;
	}

	if (is_machine_account) {
		char *lower_realm;

		lower_realm = strlower_talloc(tmp_ctx, realm);
		if (lower_realm == NULL) {
			*error_string = "Cannot allocate to lower case realm";
			goto out;
		}

		*salt_principal = talloc_asprintf(mem_ctx,
						  "host/%s.%s@%s",
						  machine_username,
						  lower_realm,
						  upper_realm);
	} else {
		*salt_principal = talloc_asprintf(mem_ctx,
						  "%s@%s",
						  machine_username,
						  upper_realm);
	}
	if (*salt_principal == NULL) {
		*error_string = "Cannot create salt principal";
		goto out;
	}

	rc = 0;
out:
	talloc_free(tmp_ctx);
	return rc;
}
static bool test_plaintext(enum ntlm_break break_which)
{
	NTSTATUS nt_status;
	uint32 flags = 0;
	DATA_BLOB nt_response = data_blob_null;
	DATA_BLOB lm_response = data_blob_null;
	char *password;
	smb_ucs2_t *nt_response_ucs2;
	size_t converted_size;

	uchar user_session_key[16];
	uchar lm_key[16];
	static const uchar zeros[8] = { 0, };
	DATA_BLOB chall = data_blob(zeros, sizeof(zeros));
	char *error_string;

	ZERO_STRUCT(user_session_key);
	
	flags |= WBFLAG_PAM_LMKEY;
	flags |= WBFLAG_PAM_USER_SESSION_KEY;

	if (!push_ucs2_talloc(talloc_tos(), &nt_response_ucs2, opt_password,
				&converted_size))
	{
		DEBUG(0, ("push_ucs2_talloc failed!\n"));
		exit(1);
	}

	nt_response.data = (unsigned char *)nt_response_ucs2;
	nt_response.length = strlen_w(nt_response_ucs2)*sizeof(smb_ucs2_t);

	if ((password = strupper_talloc(talloc_tos(), opt_password)) == NULL) {
		DEBUG(0, ("strupper_talloc() failed!\n"));
		exit(1);
	}

	if (!convert_string_talloc(talloc_tos(), CH_UNIX,
				   CH_DOS, password,
				   strlen(password)+1, 
				   &lm_response.data,
				   &lm_response.length, True)) {
		DEBUG(0, ("convert_string_talloc failed!\n"));
		exit(1);
	}

	TALLOC_FREE(password);

	switch (break_which) {
	case BREAK_NONE:
		break;
	case BREAK_LM:
		lm_response.data[0]++;
		break;
	case BREAK_NT:
		nt_response.data[0]++;
		break;
	case NO_LM:
		TALLOC_FREE(lm_response.data);
		lm_response.length = 0;
		break;
	case NO_NT:
		TALLOC_FREE(nt_response.data);
		nt_response.length = 0;
		break;
	}

	nt_status = contact_winbind_auth_crap(opt_username, opt_domain, 
					      opt_workstation,
					      &chall,
					      &lm_response,
					      &nt_response,
					      flags,
					      lm_key,
					      user_session_key,
					      &error_string, NULL);
	
	TALLOC_FREE(nt_response.data);
	TALLOC_FREE(lm_response.data);
	data_blob_free(&chall);

	if (!NT_STATUS_IS_OK(nt_status)) {
		d_printf("%s (0x%x)\n", 
			 error_string,
			 NT_STATUS_V(nt_status));
		SAFE_FREE(error_string);
		return break_which == BREAK_NT;
	}

        return break_which != BREAK_NT;
}
Exemple #15
0
static bool process_one(struct loadparm_context *lp_ctx, struct tevent_context *ev,
			struct interface *ifaces, const char *name, int nbt_port)
{
	TALLOC_CTX *tmp_ctx = talloc_new(NULL);
	enum nbt_name_type node_type = NBT_NAME_CLIENT;
	char *node_name, *p;
	struct socket_address *all_zero_addr;
	struct nbt_name_socket *nbtsock;
	NTSTATUS status = NT_STATUS_OK;
	bool ret = true;

	if (!options.case_sensitive) {
		name = strupper_talloc(tmp_ctx, name);
	}
	
	if (options.find_master) {
		node_type = NBT_NAME_MASTER;
		if (*name == '-' || *name == '_') {
			name = "\01\02__MSBROWSE__\02";
			node_type = NBT_NAME_MS;
		}
	}

	p = strchr(name, '#');
	if (p) {
		node_name = talloc_strndup(tmp_ctx, name, PTR_DIFF(p,name));
		node_type = (enum nbt_name_type)strtol(p+1, NULL, 16);
	} else {
		node_name = talloc_strdup(tmp_ctx, name);
	}

	nbtsock = nbt_name_socket_init(tmp_ctx, ev, lp_iconv_convenience(lp_ctx));
	
	if (options.root_port) {
		all_zero_addr = socket_address_from_strings(tmp_ctx, nbtsock->sock->backend_name, 
							    "0.0.0.0", NBT_NAME_SERVICE_PORT);
		
		if (!all_zero_addr) {
			talloc_free(tmp_ctx);
			return false;
		}

		status = socket_listen(nbtsock->sock, all_zero_addr, 0, 0);
		if (!NT_STATUS_IS_OK(status)) {
			printf("Failed to bind to local port 137 - %s\n", nt_errstr(status));
			talloc_free(tmp_ctx);
			return false;
		}
	}

	if (options.lookup_by_ip) {
		ret = do_node_status(nbtsock, name, nbt_port);
		talloc_free(tmp_ctx);
		return ret;
	}

	if (options.broadcast_address) {
		status = do_node_query(nbtsock, options.broadcast_address, nbt_port,
				       node_name, node_type, true);
	} else if (options.unicast_address) {
		status = do_node_query(nbtsock, options.unicast_address, 
				       nbt_port, node_name, node_type, false);
	} else {
		int i, num_interfaces;

		num_interfaces = iface_count(ifaces);
		for (i=0;i<num_interfaces;i++) {
			const char *bcast = iface_n_bcast(ifaces, i);
			if (bcast == NULL) continue;
			status = do_node_query(nbtsock, bcast, nbt_port, 
					       node_name, node_type, true);
			if (NT_STATUS_IS_OK(status)) break;
		}
	}

	if (!NT_STATUS_IS_OK(status)) {
		printf("Lookup failed - %s\n", nt_errstr(status));
		ret = false;
	}

	talloc_free(tmp_ctx);
	return ret;
}
Exemple #16
0
static krb5_error_code salt_principal_from_msg(TALLOC_CTX *parent_ctx, 
					       struct ldb_message *msg, 
					       struct smb_krb5_context *smb_krb5_context,
					       krb5_principal *salt_princ,
					       const char **error_string)
{
	const char *salt_principal = ldb_msg_find_attr_as_string(msg, "saltPrincipal", NULL);
	const char *samAccountName = ldb_msg_find_attr_as_string(msg, "samAccountName", NULL);
	const char *realm = ldb_msg_find_attr_as_string(msg, "realm", NULL);
	if (salt_principal) {
		return parse_principal(parent_ctx, salt_principal, smb_krb5_context, salt_princ, error_string);
	} else if (samAccountName) {
		krb5_error_code ret;
		char *machine_username;
		char *salt_body;
		char *lower_realm;
		char *upper_realm;

		TALLOC_CTX *tmp_ctx;
		struct principal_container *mem_ctx = talloc(parent_ctx, struct principal_container);
		if (!mem_ctx) {
			*error_string = "Cannot allocate mem_ctx";
			return ENOMEM;
		}

		tmp_ctx = talloc_new(mem_ctx);
		if (!tmp_ctx) {
			talloc_free(mem_ctx);
			*error_string = "Cannot allocate tmp_ctx";
			return ENOMEM;
		}

		if (!realm) {
			*error_string = "Cannot have a kerberos secret in secrets.ldb without a realm";
			return EINVAL;
		}
		
		machine_username = talloc_strdup(tmp_ctx, samAccountName);
		if (!machine_username) {
			talloc_free(mem_ctx);
			*error_string = "Cannot duplicate samAccountName";
			return ENOMEM;
		}
		
		if (machine_username[strlen(machine_username)-1] == '$') {
			machine_username[strlen(machine_username)-1] = '\0';
		}

		lower_realm = strlower_talloc(tmp_ctx, realm);
		if (!lower_realm) {
			talloc_free(mem_ctx);
			*error_string = "Cannot allocate to lower case realm";
			return ENOMEM;
		}
		
		upper_realm = strupper_talloc(tmp_ctx, realm);
		if (!upper_realm) {
			talloc_free(mem_ctx);
			*error_string = "Cannot allocate to upper case realm";
			return ENOMEM;
		}
		
		salt_body = talloc_asprintf(tmp_ctx, "%s.%s", machine_username, 
					    lower_realm);
		talloc_free(lower_realm);
		talloc_free(machine_username);
		if (!salt_body) {
			talloc_free(mem_ctx);
			*error_string = "Cannot form salt principal body";
			return ENOMEM;
		}
		
		ret = krb5_make_principal(smb_krb5_context->krb5_context, salt_princ, 
					  upper_realm,
					  "host", salt_body, NULL);
		if (ret == 0) {
			/* This song-and-dance effectivly puts the principal
			 * into talloc, so we can't loose it. */
			mem_ctx->smb_krb5_context = talloc_reference(mem_ctx, smb_krb5_context);
			mem_ctx->principal = *salt_princ;
			talloc_set_destructor(mem_ctx, free_principal);
		} else {
			(*error_string) = smb_get_krb5_error_message(smb_krb5_context->krb5_context, ret, parent_ctx);
		}
		talloc_free(tmp_ctx);
		return ret;
	} else {
Exemple #17
0
static krb5_error_code principals_from_msg(TALLOC_CTX *parent_ctx,
					   struct ldb_message *msg,
					   struct smb_krb5_context *smb_krb5_context,
					   struct principal_container ***principals_out,
					   const char **error_string)
{
	unsigned int i;
	krb5_error_code ret;
	char *upper_realm;
	const char *realm = ldb_msg_find_attr_as_string(msg, "realm", NULL);
	const char *samAccountName = ldb_msg_find_attr_as_string(msg, "samAccountName", NULL);
	struct ldb_message_element *spn_el = ldb_msg_find_element(msg, "servicePrincipalName");
	TALLOC_CTX *tmp_ctx;
	struct principal_container **principals;
	tmp_ctx = talloc_new(parent_ctx);
	if (!tmp_ctx) {
		*error_string = "Cannot allocate tmp_ctx";
		return ENOMEM;
	}

	if (!realm) {
		*error_string = "Cannot have a kerberos secret in secrets.ldb without a realm";
		return EINVAL;
	}

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

	principals = talloc_array(tmp_ctx, struct principal_container *, spn_el ? (spn_el->num_values + 2) : 2);

	spn_el = ldb_msg_find_element(msg, "servicePrincipalName");
	for (i=0; spn_el && i < spn_el->num_values; i++) {
		principals[i] = talloc(principals, struct principal_container);
		if (!principals[i]) {
			talloc_free(tmp_ctx);
			*error_string = "Cannot allocate mem_ctx";
			return ENOMEM;
		}

		principals[i]->smb_krb5_context = talloc_reference(principals[i], smb_krb5_context);
		principals[i]->string_form = talloc_asprintf(principals[i], "%*.*s@%s",
							     (int)spn_el->values[i].length,
							     (int)spn_el->values[i].length,
							     (const char *)spn_el->values[i].data, upper_realm);
		if (!principals[i]->string_form) {
			talloc_free(tmp_ctx);
			*error_string = "Cannot allocate full samAccountName";
			return ENOMEM;
		}

		ret = krb5_parse_name(smb_krb5_context->krb5_context,
				      principals[i]->string_form, &principals[i]->principal);
		
		if (ret) {
			talloc_free(tmp_ctx);
			(*error_string) = smb_get_krb5_error_message(smb_krb5_context->krb5_context, ret, parent_ctx);
			return ret;
		}

		/* This song-and-dance effectivly puts the principal
		 * into talloc, so we can't loose it. */
		talloc_set_destructor(principals[i], free_principal);
	}

	if (samAccountName) {
		principals[i] = talloc(principals, struct principal_container);
		if (!principals[i]) {
			talloc_free(tmp_ctx);
			*error_string = "Cannot allocate mem_ctx";
			return ENOMEM;
		}

		principals[i]->smb_krb5_context = talloc_reference(principals[i], smb_krb5_context);
		principals[i]->string_form = talloc_asprintf(parent_ctx, "%s@%s", samAccountName, upper_realm);
		if (!principals[i]->string_form) {
			talloc_free(tmp_ctx);
			*error_string = "Cannot allocate full samAccountName";
			return ENOMEM;
		}
		
		ret = krb5_make_principal(smb_krb5_context->krb5_context, &principals[i]->principal, upper_realm, samAccountName,
					  NULL);
		if (ret) {
			talloc_free(tmp_ctx);
			(*error_string) = smb_get_krb5_error_message(smb_krb5_context->krb5_context, ret, parent_ctx);
			return ret;
		}
		
		/* This song-and-dance effectivly puts the principal
		 * into talloc, so we can't loose it. */
		talloc_set_destructor(principals[i], free_principal);
		i++;
	}

	principals[i] = NULL;
	*principals_out = talloc_steal(parent_ctx, principals);

	talloc_free(tmp_ctx);
	return ret;
}
Exemple #18
0
static krb5_error_code salt_principal(TALLOC_CTX *parent_ctx,
                                      const char *samAccountName,
                                      const char *realm,
                                      const char *saltPrincipal,
                                      krb5_context context,
                                      krb5_principal *salt_princ,
                                      const char **error_string)
{

    krb5_error_code ret;
    char *machine_username;
    char *salt_body;
    char *lower_realm;
    char *upper_realm;

    TALLOC_CTX *tmp_ctx;

    if (saltPrincipal) {
        ret = krb5_parse_name(context, saltPrincipal, salt_princ);
        if (ret) {
            *error_string = smb_get_krb5_error_message(
                                context, ret, parent_ctx);
        }
        return ret;
    }

    if (!samAccountName) {
        (*error_string) = "Cannot determine salt principal, no "
                          "saltPrincipal or samAccountName specified";
        return EINVAL;
    }

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

    tmp_ctx = talloc_new(parent_ctx);
    if (!tmp_ctx) {
        *error_string = "Cannot allocate tmp_ctx";
        return ENOMEM;
    }

    machine_username = talloc_strdup(tmp_ctx, samAccountName);
    if (!machine_username) {
        *error_string = "Cannot duplicate samAccountName";
        talloc_free(tmp_ctx);
        return ENOMEM;
    }

    if (machine_username[strlen(machine_username)-1] == '$') {
        machine_username[strlen(machine_username)-1] = '\0';
    }

    lower_realm = strlower_talloc(tmp_ctx, realm);
    if (!lower_realm) {
        *error_string = "Cannot allocate to lower case realm";
        talloc_free(tmp_ctx);
        return ENOMEM;
    }

    upper_realm = strupper_talloc(tmp_ctx, realm);
    if (!upper_realm) {
        *error_string = "Cannot allocate to upper case realm";
        talloc_free(tmp_ctx);
        return ENOMEM;
    }

    salt_body = talloc_asprintf(tmp_ctx, "%s.%s",
                                machine_username, lower_realm);
    if (!salt_body) {
        *error_string = "Cannot form salt principal body";
        talloc_free(tmp_ctx);
        return ENOMEM;
    }

    ret = smb_krb5_make_principal(context, salt_princ, upper_realm,
                                  "host", salt_body, NULL);
    if (ret) {
        *error_string = smb_get_krb5_error_message(context,
                        ret, parent_ctx);
    }

    talloc_free(tmp_ctx);
    return ret;
}
Exemple #19
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 = smb_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;
}
Exemple #20
0
/* Does both the NTLMv2 owfs of a user's password */
bool ntv2_owf_gen(const uint8_t owf[16],
		  const char *user_in, const char *domain_in,
		  uint8_t kr_buf[16])
{
	smb_ucs2_t *user;
	smb_ucs2_t *domain;
	size_t user_byte_len;
	size_t domain_byte_len;
	bool ret;

	HMACMD5Context ctx;
	TALLOC_CTX *mem_ctx = talloc_init("ntv2_owf_gen for %s\\%s", domain_in, user_in);

	if (!mem_ctx) {
		return false;
	}

	if (!user_in) {
		user_in = "";
	}

	if (!domain_in) {
		domain_in = "";
	}

	user_in = strupper_talloc(mem_ctx, user_in);
	if (user_in == NULL) {
		talloc_free(mem_ctx);
		return false;
	}

	ret = push_ucs2_talloc(mem_ctx, &user, user_in, &user_byte_len );
	if (!ret) {
		DEBUG(0, ("push_uss2_talloc() for user failed)\n"));
		talloc_free(mem_ctx);
		return false;
	}

	ret = push_ucs2_talloc(mem_ctx, &domain, domain_in, &domain_byte_len);
	if (!ret) {
		DEBUG(0, ("push_ucs2_talloc() for domain failed\n"));
		talloc_free(mem_ctx);
		return false;
	}

	SMB_ASSERT(user_byte_len >= 2);
	SMB_ASSERT(domain_byte_len >= 2);

	/* We don't want null termination */
	user_byte_len = user_byte_len - 2;
	domain_byte_len = domain_byte_len - 2;

	hmac_md5_init_limK_to_64(owf, 16, &ctx);
	hmac_md5_update((uint8_t *)user, user_byte_len, &ctx);
	hmac_md5_update((uint8_t *)domain, domain_byte_len, &ctx);
	hmac_md5_final(kr_buf, &ctx);

#ifdef DEBUG_PASSWORD
	DEBUG(100, ("ntv2_owf_gen: user, domain, owfkey, kr\n"));
	dump_data(100, (uint8_t *)user, user_byte_len);
	dump_data(100, (uint8_t *)domain, domain_byte_len);
	dump_data(100, owf, 16);
	dump_data(100, kr_buf, 16);
#endif

	talloc_free(mem_ctx);
	return true;
}
Exemple #21
0
NTSTATUS gp_create_gpo (struct gp_context *gp_ctx, const char *display_name, struct gp_object **ret)
{
	struct GUID guid_struct;
	char *guid_str;
	char *name;
	struct security_descriptor *sd;
	TALLOC_CTX *mem_ctx;
	struct gp_object *gpo;
	NTSTATUS status;

	/* Create a forked memory context, as a base for everything here */
	mem_ctx = talloc_new(gp_ctx);
	NT_STATUS_HAVE_NO_MEMORY(mem_ctx);

	/* Create the gpo struct to return later */
	gpo = talloc(gp_ctx, struct gp_object);
	if (gpo == NULL) {
		TALLOC_FREE(mem_ctx);
		return NT_STATUS_NO_MEMORY;
	}

	/* Generate a GUID */
	guid_struct = GUID_random();
	guid_str = GUID_string2(mem_ctx, &guid_struct);
	if (guid_str == NULL) {
		TALLOC_FREE(mem_ctx);
		return NT_STATUS_NO_MEMORY;
	}
	name = strupper_talloc(mem_ctx, guid_str);
	if (name == NULL) {
		TALLOC_FREE(mem_ctx);
		return NT_STATUS_NO_MEMORY;
	}

	/* Prepare the GPO struct */
	gpo->dn = NULL;
	gpo->name = name;
	gpo->flags = 0;
	gpo->version = 0;
	gpo->display_name = talloc_strdup(gpo, display_name);
	if (gpo->display_name == NULL) {
		TALLOC_FREE(mem_ctx);
		return NT_STATUS_NO_MEMORY;
	}

	gpo->file_sys_path = talloc_asprintf(gpo, "\\\\%s\\sysvol\\%s\\Policies\\%s", lpcfg_dnsdomain(gp_ctx->lp_ctx), lpcfg_dnsdomain(gp_ctx->lp_ctx), name);
	if (gpo->file_sys_path == NULL) {
		TALLOC_FREE(mem_ctx);
		return NT_STATUS_NO_MEMORY;
	}

	/* Create the GPT */
	status = gp_create_gpt(gp_ctx, name, gpo->file_sys_path);
	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(0, ("Failed to create GPT\n"));
		talloc_free(mem_ctx);
		return status;
	}


	/* Create the LDAP GPO, including CN=User and CN=Machine */
	status = gp_create_ldap_gpo(gp_ctx, gpo);
	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(0, ("Failed to create LDAP group policy object\n"));
		talloc_free(mem_ctx);
		return status;
	}

	/* Get the new security descriptor */
	status = gp_get_gpo_info(gp_ctx, gpo->dn, &gpo);
	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(0, ("Failed to fetch LDAP group policy object\n"));
		talloc_free(mem_ctx);
		return status;
	}

	/* Create matching file and DS security descriptors */
	status = gp_create_gpt_security_descriptor(mem_ctx, gpo->security_descriptor, &sd);
	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(0, ("Failed to convert ADS security descriptor to filesystem security descriptor\n"));
		talloc_free(mem_ctx);
		return status;
	}

	/* Set the security descriptor on the filesystem for this GPO */
	status = gp_set_gpt_security_descriptor(gp_ctx, gpo, sd);
	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(0, ("Failed to set security descriptor (ACL) on the file system\n"));
		talloc_free(mem_ctx);
		return status;
	}

	talloc_free(mem_ctx);

	*ret = gpo;
	return NT_STATUS_OK;
}
Exemple #22
0
static bool torture_ldb_dn_extended(struct torture_context *torture)
{
    TALLOC_CTX *mem_ctx = talloc_new(torture);
    struct ldb_context *ldb;
    struct ldb_dn *dn, *dn2;

    DATA_BLOB sid_blob = strhex_to_data_blob(mem_ctx, hex_sid);
    DATA_BLOB guid_blob = strhex_to_data_blob(mem_ctx, hex_guid);

    const char *dn_str = "cn=admin,cn=users,dc=samba,dc=org";

    torture_assert(torture,
                   ldb = ldb_init(mem_ctx, torture->ev),
                   "Failed to init ldb");

    torture_assert_int_equal(torture,
                             ldb_register_samba_handlers(ldb), 0,
                             "Failed to register Samba handlers");

    ldb_set_utf8_fns(ldb, NULL, wrap_casefold);

    /* Check behaviour of a normal DN */
    torture_assert(torture,
                   dn = ldb_dn_new(mem_ctx, ldb, dn_str),
                   "Failed to create a 'normal' DN");

    torture_assert(torture,
                   ldb_dn_validate(dn),
                   "Failed to validate 'normal' DN");

    torture_assert(torture, ldb_dn_has_extended(dn) == false,
                   "Should not find plain DN to be 'extended'");

    torture_assert(torture, ldb_dn_get_extended_component(dn, "SID") == NULL,
                   "Should not find an SID on plain DN");

    torture_assert(torture, ldb_dn_get_extended_component(dn, "GUID") == NULL,
                   "Should not find an GUID on plain DN");

    torture_assert(torture, ldb_dn_get_extended_component(dn, "WKGUID") == NULL,
                   "Should not find an WKGUID on plain DN");

    /* Now make an extended DN */
    torture_assert(torture,
                   dn = ldb_dn_new_fmt(mem_ctx, ldb, "<GUID=%s>;<SID=%s>;%s",
                                       guid, sid, dn_str),
                   "Failed to create an 'extended' DN");

    torture_assert(torture,
                   dn2 = ldb_dn_copy(mem_ctx, dn),
                   "Failed to copy the 'extended' DN");
    talloc_free(dn);
    dn = dn2;

    torture_assert(torture,
                   ldb_dn_validate(dn),
                   "Failed to validate 'extended' DN");

    torture_assert(torture, ldb_dn_has_extended(dn) == true,
                   "Should find extended DN to be 'extended'");

    torture_assert(torture, ldb_dn_get_extended_component(dn, "SID") != NULL,
                   "Should find an SID on extended DN");

    torture_assert(torture, ldb_dn_get_extended_component(dn, "GUID") != NULL,
                   "Should find an GUID on extended DN");

    torture_assert_data_blob_equal(torture, *ldb_dn_get_extended_component(dn, "SID"), sid_blob,
                                   "Extended DN SID incorect");

    torture_assert_data_blob_equal(torture, *ldb_dn_get_extended_component(dn, "GUID"), guid_blob,
                                   "Extended DN GUID incorect");

    torture_assert_str_equal(torture, ldb_dn_get_linearized(dn), dn_str,
                             "linearized DN incorrect");

    torture_assert_str_equal(torture, ldb_dn_get_casefold(dn), strupper_talloc(mem_ctx, dn_str),
                             "casefolded DN incorrect");

    torture_assert_str_equal(torture, ldb_dn_get_component_name(dn, 0), "cn",
                             "componet zero incorrect");

    torture_assert_data_blob_equal(torture, *ldb_dn_get_component_val(dn, 0), data_blob_string_const("admin"),
                                   "componet zero incorrect");

    torture_assert_str_equal(torture, ldb_dn_get_extended_linearized(mem_ctx, dn, 1),
                             talloc_asprintf(mem_ctx, "<GUID=%s>;<SID=%s>;%s",
                                     guid, sid, dn_str),
                             "Clear extended linearized DN incorrect");

    torture_assert_str_equal(torture, ldb_dn_get_extended_linearized(mem_ctx, dn, 0),
                             talloc_asprintf(mem_ctx, "<GUID=%s>;<SID=%s>;%s",
                                     hex_guid, hex_sid, dn_str),
                             "HEX extended linearized DN incorrect");

    torture_assert(torture, ldb_dn_remove_child_components(dn, 1) == true,
                   "Failed to remove DN child");

    torture_assert(torture, ldb_dn_has_extended(dn) == false,
                   "Extended DN flag should be cleared after child element removal");

    torture_assert(torture, ldb_dn_get_extended_component(dn, "SID") == NULL,
                   "Should not find an SID on DN");

    torture_assert(torture, ldb_dn_get_extended_component(dn, "GUID") == NULL,
                   "Should not find an GUID on DN");


    /* TODO:  test setting these in the other order, and ensure it still comes out 'GUID first' */
    torture_assert_int_equal(torture, ldb_dn_set_extended_component(dn, "GUID", &guid_blob), 0,
                             "Failed to set a GUID on DN");

    torture_assert_int_equal(torture, ldb_dn_set_extended_component(dn, "SID", &sid_blob), 0,
                             "Failed to set a SID on DN");

    torture_assert_data_blob_equal(torture, *ldb_dn_get_extended_component(dn, "SID"), sid_blob,
                                   "Extended DN SID incorect");

    torture_assert_data_blob_equal(torture, *ldb_dn_get_extended_component(dn, "GUID"), guid_blob,
                                   "Extended DN GUID incorect");

    torture_assert_str_equal(torture, ldb_dn_get_linearized(dn), "cn=users,dc=samba,dc=org",
                             "linearized DN incorrect");

    torture_assert_str_equal(torture, ldb_dn_get_extended_linearized(mem_ctx, dn, 1),
                             talloc_asprintf(mem_ctx, "<GUID=%s>;<SID=%s>;%s",
                                     guid, sid, "cn=users,dc=samba,dc=org"),
                             "Clear extended linearized DN incorrect");

    torture_assert_str_equal(torture, ldb_dn_get_extended_linearized(mem_ctx, dn, 0),
                             talloc_asprintf(mem_ctx, "<GUID=%s>;<SID=%s>;%s",
                                     hex_guid, hex_sid, "cn=users,dc=samba,dc=org"),
                             "HEX extended linearized DN incorrect");

    /* Now check a 'just GUID' DN (clear format) */
    torture_assert(torture,
                   dn = ldb_dn_new_fmt(mem_ctx, ldb, "<GUID=%s>",
                                       guid),
                   "Failed to create an 'extended' DN");

    torture_assert(torture,
                   ldb_dn_validate(dn),
                   "Failed to validate 'extended' DN");

    torture_assert(torture, ldb_dn_has_extended(dn) == true,
                   "Should find extended DN to be 'extended'");

    torture_assert(torture, ldb_dn_get_extended_component(dn, "SID") == NULL,
                   "Should not find an SID on this DN");

    torture_assert_int_equal(torture, ldb_dn_get_comp_num(dn), 0,
                             "Should not find an 'normal' componet on this DN");

    torture_assert(torture, ldb_dn_get_extended_component(dn, "GUID") != NULL,
                   "Should find an GUID on this DN");

    torture_assert_data_blob_equal(torture, *ldb_dn_get_extended_component(dn, "GUID"), guid_blob,
                                   "Extended DN GUID incorect");

    torture_assert_str_equal(torture, ldb_dn_get_linearized(dn), "",
                             "linearized DN incorrect");

    torture_assert_str_equal(torture, ldb_dn_get_extended_linearized(mem_ctx, dn, 1),
                             talloc_asprintf(mem_ctx, "<GUID=%s>",
                                     guid),
                             "Clear extended linearized DN incorrect");

    torture_assert_str_equal(torture, ldb_dn_get_extended_linearized(mem_ctx, dn, 0),
                             talloc_asprintf(mem_ctx, "<GUID=%s>",
                                     hex_guid),
                             "HEX extended linearized DN incorrect");

    /* Now check a 'just GUID' DN (HEX format) */
    torture_assert(torture,
                   dn = ldb_dn_new_fmt(mem_ctx, ldb, "<GUID=%s>",
                                       hex_guid),
                   "Failed to create an 'extended' DN");

    torture_assert(torture,
                   ldb_dn_validate(dn),
                   "Failed to validate 'extended' DN");

    torture_assert(torture, ldb_dn_has_extended(dn) == true,
                   "Should find extended DN to be 'extended'");

    torture_assert(torture, ldb_dn_get_extended_component(dn, "SID") == NULL,
                   "Should not find an SID on this DN");

    torture_assert(torture, ldb_dn_get_extended_component(dn, "GUID") != NULL,
                   "Should find an GUID on this DN");

    torture_assert_data_blob_equal(torture, *ldb_dn_get_extended_component(dn, "GUID"), guid_blob,
                                   "Extended DN GUID incorect");

    torture_assert_str_equal(torture, ldb_dn_get_linearized(dn), "",
                             "linearized DN incorrect");

    /* Now check a 'just SID' DN (clear format) */
    torture_assert(torture,
                   dn = ldb_dn_new_fmt(mem_ctx, ldb, "<SID=%s>",
                                       sid),
                   "Failed to create an 'extended' DN");

    torture_assert(torture,
                   ldb_dn_validate(dn),
                   "Failed to validate 'extended' DN");

    torture_assert(torture, ldb_dn_has_extended(dn) == true,
                   "Should find extended DN to be 'extended'");

    torture_assert(torture, ldb_dn_get_extended_component(dn, "GUID") == NULL,
                   "Should not find an SID on this DN");

    torture_assert(torture, ldb_dn_get_extended_component(dn, "SID") != NULL,
                   "Should find an SID on this DN");

    torture_assert_data_blob_equal(torture, *ldb_dn_get_extended_component(dn, "SID"), sid_blob,
                                   "Extended DN SID incorect");

    torture_assert_str_equal(torture, ldb_dn_get_linearized(dn), "",
                             "linearized DN incorrect");

    torture_assert_str_equal(torture, ldb_dn_get_extended_linearized(mem_ctx, dn, 1),
                             talloc_asprintf(mem_ctx, "<SID=%s>",
                                     sid),
                             "Clear extended linearized DN incorrect");

    torture_assert_str_equal(torture, ldb_dn_get_extended_linearized(mem_ctx, dn, 0),
                             talloc_asprintf(mem_ctx, "<SID=%s>",
                                     hex_sid),
                             "HEX extended linearized DN incorrect");

    /* Now check a 'just SID' DN (HEX format) */
    torture_assert(torture,
                   dn = ldb_dn_new_fmt(mem_ctx, ldb, "<SID=%s>",
                                       hex_sid),
                   "Failed to create an 'extended' DN");

    torture_assert(torture,
                   ldb_dn_validate(dn),
                   "Failed to validate 'extended' DN");

    torture_assert(torture, ldb_dn_has_extended(dn) == true,
                   "Should find extended DN to be 'extended'");

    torture_assert(torture, ldb_dn_get_extended_component(dn, "GUID") == NULL,
                   "Should not find an SID on this DN");

    torture_assert(torture, ldb_dn_get_extended_component(dn, "SID") != NULL,
                   "Should find an SID on this DN");

    torture_assert_data_blob_equal(torture, *ldb_dn_get_extended_component(dn, "SID"), sid_blob,
                                   "Extended DN SID incorect");

    torture_assert_str_equal(torture, ldb_dn_get_linearized(dn), "",
                             "linearized DN incorrect");

    talloc_free(mem_ctx);
    return true;
}
Exemple #23
0
static
NTSTATUS schannel_fetch_session_key_tdb(struct tdb_wrap *tdb_sc,
					TALLOC_CTX *mem_ctx,
					const char *computer_name,
					struct netlogon_creds_CredentialState **pcreds)
{
	NTSTATUS status;
	TDB_DATA value;
	enum ndr_err_code ndr_err;
	DATA_BLOB blob;
	struct netlogon_creds_CredentialState *creds = NULL;
	char *keystr = NULL;
	char *name_upper;

	*pcreds = NULL;

	name_upper = strupper_talloc(mem_ctx, computer_name);
	if (!name_upper) {
		return NT_STATUS_NO_MEMORY;
	}

	keystr = talloc_asprintf(mem_ctx, "%s/%s",
				 SECRETS_SCHANNEL_STATE, name_upper);
	TALLOC_FREE(name_upper);
	if (!keystr) {
		return NT_STATUS_NO_MEMORY;
	}

	value = tdb_fetch_bystring(tdb_sc->tdb, keystr);
	if (!value.dptr) {
		DEBUG(10,("schannel_fetch_session_key_tdb: Failed to find entry with key %s\n",
			keystr ));
		status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
		goto done;
	}

	creds = talloc_zero(mem_ctx, struct netlogon_creds_CredentialState);
	if (!creds) {
		status = NT_STATUS_NO_MEMORY;
		goto done;
	}

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

	ndr_err = ndr_pull_struct_blob(&blob, creds, creds,
			(ndr_pull_flags_fn_t)ndr_pull_netlogon_creds_CredentialState);
	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
		status = ndr_map_error2ntstatus(ndr_err);
		goto done;
	}

	if (DEBUGLEVEL >= 10) {
		NDR_PRINT_DEBUG(netlogon_creds_CredentialState, creds);
	}

	DEBUG(3,("schannel_fetch_session_key_tdb: restored schannel info key %s\n",
		keystr));

	status = NT_STATUS_OK;

 done:

	talloc_free(keystr);
	SAFE_FREE(value.dptr);

	if (!NT_STATUS_IS_OK(status)) {
		talloc_free(creds);
		return status;
	}

	*pcreds = creds;

	return NT_STATUS_OK;
}