Exemple #1
0
bool torture_samba3_posixtimedlock(struct torture_context *tctx)
{
	struct smbcli_state *cli;
	NTSTATUS status;
	bool ret = true;
	const char *dirname = "posixlock";
	const char *fname = "locked";
	const char *fpath;
	const char *localdir;
	const char *localname;
	int fnum = -1;

	int fd = -1;
	struct flock posix_lock;

	union smb_lock io;
	struct smb_lock_entry lock_entry;
	struct smbcli_request *req;
	struct lock_result_state lock_result;

	struct tevent_timer *te;

	if (!torture_open_connection(&cli, tctx, 0)) {
		ret = false;
		goto done;
	}

	smbcli_deltree(cli->tree, dirname);

	status = smbcli_mkdir(cli->tree, dirname);
	if (!NT_STATUS_IS_OK(status)) {
		torture_warning(tctx, "smbcli_mkdir failed: %s\n",
				nt_errstr(status));
		ret = false;
		goto done;
	}

	if (!(fpath = talloc_asprintf(tctx, "%s\\%s", dirname, fname))) {
		torture_warning(tctx, "talloc failed\n");
		ret = false;
		goto done;
	}
	fnum = smbcli_open(cli->tree, fpath, O_RDWR | O_CREAT, DENY_NONE);
	if (fnum == -1) {
		torture_warning(tctx, "Could not create file %s: %s\n", fpath,
				smbcli_errstr(cli->tree));
		ret = false;
		goto done;
	}

	if (!(localdir = torture_setting_string(tctx, "localdir", NULL))) {
		torture_warning(tctx, "Need 'localdir' setting\n");
		ret = false;
		goto done;
	}

	if (!(localname = talloc_asprintf(tctx, "%s/%s/%s", localdir, dirname,
					  fname))) {
		torture_warning(tctx, "talloc failed\n");
		ret = false;
		goto done;
	}

	/*
	 * Lock a byte range from posix
	 */

	fd = open(localname, O_RDWR);
	if (fd == -1) {
		torture_warning(tctx, "open(%s) failed: %s\n",
				localname, strerror(errno));
		goto done;
	}

	posix_lock.l_type = F_WRLCK;
	posix_lock.l_whence = SEEK_SET;
	posix_lock.l_start = 0;
	posix_lock.l_len = 1;

	if (fcntl(fd, F_SETLK, &posix_lock) == -1) {
		torture_warning(tctx, "fcntl failed: %s\n", strerror(errno));
		ret = false;
		goto done;
	}

	/*
	 * Try a cifs brlock without timeout to see if posix locking = yes
	 */

	io.lockx.in.ulock_cnt = 0;
	io.lockx.in.lock_cnt = 1;

	lock_entry.count = 1;
	lock_entry.offset = 0;
	lock_entry.pid = cli->tree->session->pid;

	io.lockx.level = RAW_LOCK_LOCKX;
	io.lockx.in.mode = LOCKING_ANDX_LARGE_FILES;
	io.lockx.in.timeout = 0;
	io.lockx.in.locks = &lock_entry;
	io.lockx.in.file.fnum = fnum;

	status = smb_raw_lock(cli->tree, &io);

	ret = true;
	CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT);

	if (!ret) {
		goto done;
	}

	/*
	 * Now fire off a timed brlock, unlock the posix lock and see if the
	 * timed lock gets through.
	 */

	io.lockx.in.timeout = 5000;

	req = smb_raw_lock_send(cli->tree, &io);
	if (req == NULL) {
		torture_warning(tctx, "smb_raw_lock_send failed\n");
		ret = false;
		goto done;
	}

	lock_result.done = false;
	req->async.fn = receive_lock_result;
	req->async.private_data = &lock_result;

	te = tevent_add_timer(req->transport->socket->event.ctx,
			      tctx, timeval_current_ofs(1, 0),
			      close_locked_file, &fd);
	if (te == NULL) {
		torture_warning(tctx, "tevent_add_timer failed\n");
		ret = false;
		goto done;
	}

	while ((fd != -1) || (!lock_result.done)) {
		if (tevent_loop_once(req->transport->socket->event.ctx)
		    == -1) {
			torture_warning(tctx, "tevent_loop_once failed: %s\n",
					strerror(errno));
			ret = false;
			goto done;
		}
	}

	CHECK_STATUS(lock_result.status, NT_STATUS_OK);

 done:
	if (fnum != -1) {
		smbcli_close(cli->tree, fnum);
	}
	if (fd != -1) {
		close(fd);
	}
	smbcli_deltree(cli->tree, dirname);
	return ret;
}
Exemple #2
0
static ADS_STATUS ads_guess_service_principal(ADS_STRUCT *ads,
					      char **returned_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;
	}

	rc = asprintf(&princ, "ldap/%[email protected]%s", server, realm);
	if (rc == -1 || princ == NULL) {
		status = ADS_ERROR(LDAP_PARAM_ERROR);
		goto out;
	}

	*returned_principal = princ;

	status = ADS_SUCCESS;
out:
	TALLOC_FREE(frame);
	return status;
}
Exemple #3
0
void setup_simple(void)
{
    errno_t ret;
    char *conf_db;
    const char *val[2];
    val[1] = NULL;

    fail_unless(test_ctx == NULL, "Simple context already initialized.");
    test_ctx = talloc_zero(NULL, struct simple_test_ctx);
    fail_unless(test_ctx != NULL, "Cannot create simple test context.");

    test_ctx->ev = tevent_context_init(test_ctx);
    fail_unless(test_ctx->ev != NULL, "Cannot create tevent context.");

    test_ctx->ctx = talloc_zero(test_ctx, struct simple_ctx);
    fail_unless(test_ctx->ctx != NULL, "Cannot create simple context.");

    /* Create tests directory if it doesn't exist */
    /* (relative to current dir) */
    ret = mkdir(TESTS_PATH, 0775);
    fail_if(ret == -1 && errno != EEXIST,
            "Could not create %s directory", TESTS_PATH);

    conf_db = talloc_asprintf(test_ctx, "%s/%s", TESTS_PATH, TEST_CONF_FILE);
    fail_if(conf_db == NULL, "Out of memory, aborting!");
    DEBUG(SSSDBG_TRACE_LIBS, "CONFDB: %s\n", conf_db);

    /* Connect to the conf db */
    ret = confdb_init(test_ctx, &test_ctx->confdb, conf_db);
    fail_if(ret != EOK, "Could not initialize connection to the confdb");

    val[0] = "LOCAL";
    ret = confdb_add_param(test_ctx->confdb, true,
                           "config/sssd", "domains", val);
    fail_if(ret != EOK, "Could not initialize domains placeholder");

    val[0] = "local";
    ret = confdb_add_param(test_ctx->confdb, true,
                           "config/domain/LOCAL", "id_provider", val);
    fail_if(ret != EOK, "Could not initialize provider");

    val[0] = "TRUE";
    ret = confdb_add_param(test_ctx->confdb, true,
                           "config/domain/LOCAL", "enumerate", val);
    fail_if(ret != EOK, "Could not initialize LOCAL domain");

    val[0] = "TRUE";
    ret = confdb_add_param(test_ctx->confdb, true,
                           "config/domain/LOCAL", "cache_credentials", val);
    fail_if(ret != EOK, "Could not initialize LOCAL domain");

    ret = sssd_domain_init(test_ctx, test_ctx->confdb, "local",
                           TESTS_PATH, &test_ctx->ctx->domain);
    fail_if(ret != EOK, "Could not initialize connection to the sysdb (%d)", ret);
    test_ctx->sysdb = test_ctx->ctx->domain->sysdb;
    test_ctx->ctx->domain->case_sensitive = true;
    test_ctx->ctx->domain->mpg = false; /* Simulate an LDAP domain better */

    /* be_ctx */
    test_ctx->be_ctx = talloc_zero(test_ctx, struct be_ctx);
    fail_if(test_ctx->be_ctx == NULL, "Unable to setup be_ctx");

    test_ctx->be_ctx->cdb = test_ctx->confdb;
    test_ctx->be_ctx->ev = test_ctx->ev;
    test_ctx->be_ctx->conf_path = "config/domain/LOCAL";
    test_ctx->be_ctx->domain = test_ctx->ctx->domain;

    test_ctx->ctx->be_ctx = test_ctx->be_ctx;

    ret = sss_names_init(test_ctx->ctx->domain, test_ctx->confdb,
                         "LOCAL", &test_ctx->be_ctx->domain->names);
    fail_if(ret != EOK, "Unable to setup domain names (%d)", ret);
}
Exemple #4
0
NSS_STATUS _nss_ldb_getgrgid_r(gid_t gid, struct group *result_buf, char *buffer, size_t buflen, int *errnop)
{
    int ret;
    char *filter;
    TALLOC_CTX *ctx;
    struct ldb_result *gr_res;
    struct ldb_result *mem_res;

    if (gid == 0) { /* we don't serve root gid by policy */
        *errnop = errno = ENOENT;
        return NSS_STATUS_NOTFOUND;
    }

    ret = _ldb_nss_init();
    if (ret != NSS_STATUS_SUCCESS) {
        return ret;
    }

    ctx = talloc_new(_ldb_nss_ctx->ldb);
    if ( ! ctx) {
        *errnop = errno = ENOMEM;
        return NSS_STATUS_UNAVAIL;
    }

    /* build the filter for this uid */
    filter = talloc_asprintf(ctx, _LDB_NSS_GRGID_FILTER, gid);
    if (filter == NULL) {
        /* this is a fatal error */
        *errnop = errno = ENOMEM;
        ret = NSS_STATUS_UNAVAIL;
        goto done;
    }

    /* search the entry */
    ret = ldb_search(_ldb_nss_ctx->ldb,
                     _ldb_nss_ctx->base,
                     LDB_SCOPE_SUBTREE,
                     filter,
                     _ldb_nss_gr_attrs,
                     &gr_res);
    if (ret != LDB_SUCCESS) {
        /* this is a fatal error */
        *errnop = errno = ENOENT;
        ret = NSS_STATUS_UNAVAIL;
        goto done;
    }

    talloc_steal(ctx, gr_res);

    /* if none found return */
    if (gr_res->count == 0) {
        *errnop = errno = ENOENT;
        ret = NSS_STATUS_NOTFOUND;
        goto done;
    }

    if (gr_res->count != 1) {
        /* this is a fatal error */
        *errnop = errno = ENOENT;
        ret = NSS_STATUS_UNAVAIL;
        goto done;
    }

    mem_res = talloc_zero(ctx, struct ldb_result);
    if ( ! mem_res) {
        errno = *errnop = ENOMEM;
        ret = NSS_STATUS_UNAVAIL;
        goto done;
    }

    ret = _ldb_nss_group_request(&mem_res,
                                 gr_res->msgs[0]->dn,
                                 _ldb_nss_mem_attrs,
                                 "member");

    if (ret != NSS_STATUS_SUCCESS) {
        *errnop = errno;
        goto done;
    }

    ret = _ldb_nss_fill_group(result_buf,
                              buffer,
                              buflen,
                              errnop,
                              gr_res->msgs[0],
                              mem_res);

    if (ret != NSS_STATUS_SUCCESS) {
        goto done;
    }

    ret = NSS_STATUS_SUCCESS;
done:
    talloc_free(ctx);
    return ret;
}
WERROR gp_reg_state_store(TALLOC_CTX *mem_ctx,
			  uint32_t flags,
			  const char *dn,
			  const struct nt_user_token *token,
			  struct GROUP_POLICY_OBJECT *gpo_list)
{
	struct gp_registry_context *reg_ctx = NULL;
	WERROR werr = WERR_GENERAL_FAILURE;
	const char *subkeyname = NULL;
	struct GROUP_POLICY_OBJECT *gpo;
	int count = 0;
	struct registry_key *key;

	werr = gp_init_reg_ctx(mem_ctx, KEY_GROUP_POLICY, REG_KEY_WRITE,
			       token, &reg_ctx);
	W_ERROR_NOT_OK_RETURN(werr);

	werr = gp_secure_key(mem_ctx, flags, reg_ctx->curr_key,
			     &token->user_sids[0]);
	if (!W_ERROR_IS_OK(werr)) {
		DEBUG(0,("failed to secure key: %s\n", dos_errstr(werr)));
		goto done;
	}

	werr = gp_reg_store_groupmembership(mem_ctx, reg_ctx, token, flags);
	if (!W_ERROR_IS_OK(werr)) {
		DEBUG(0,("failed to store group membership: %s\n", dos_errstr(werr)));
		goto done;
	}

	subkeyname = gp_req_state_path(mem_ctx, &token->user_sids[0], flags);
	if (!subkeyname) {
		werr = WERR_NOMEM;
		goto done;
	}

	werr = gp_del_reg_state(mem_ctx, reg_ctx->curr_key, subkeyname);
	if (!W_ERROR_IS_OK(werr)) {
		DEBUG(0,("failed to delete old state: %s\n", dos_errstr(werr)));
		/* goto done; */
	}

	werr = gp_store_reg_subkey(mem_ctx, subkeyname,
				   reg_ctx->curr_key, &reg_ctx->curr_key);
	if (!W_ERROR_IS_OK(werr)) {
		goto done;
	}

	werr = gp_store_reg_val_sz(mem_ctx, reg_ctx->curr_key,
				   "Distinguished-Name", dn);
	if (!W_ERROR_IS_OK(werr)) {
		goto done;
	}

	/* store link list */

	werr = gp_store_reg_subkey(mem_ctx, "GPLink-List",
				   reg_ctx->curr_key, &key);
	if (!W_ERROR_IS_OK(werr)) {
		goto done;
	}

	/* store gpo list */

	werr = gp_store_reg_subkey(mem_ctx, "GPO-List",
				   reg_ctx->curr_key, &reg_ctx->curr_key);
	if (!W_ERROR_IS_OK(werr)) {
		goto done;
	}

	for (gpo = gpo_list; gpo; gpo = gpo->next) {

		subkeyname = talloc_asprintf(mem_ctx, "%d", count++);
		if (!subkeyname) {
			werr = WERR_NOMEM;
			goto done;
		}

		werr = gp_store_reg_subkey(mem_ctx, subkeyname,
					   reg_ctx->curr_key, &key);
		if (!W_ERROR_IS_OK(werr)) {
			goto done;
		}

		werr = gp_store_reg_gpovals(mem_ctx, key, gpo);
		if (!W_ERROR_IS_OK(werr)) {
			DEBUG(0,("gp_reg_state_store: "
				"gpo_store_reg_gpovals failed for %s: %s\n",
				gpo->display_name, dos_errstr(werr)));
			goto done;
		}
	}
 done:
	gp_free_reg_ctx(reg_ctx);
	return werr;
}
Exemple #6
0
static bool internal_torture_run_test(struct torture_context *context,
                                      struct torture_tcase *tcase,
                                      struct torture_test *test,
                                      bool already_setup)
{
    bool success;
    char *old_testname = NULL;

    if (tcase == NULL || strcmp(test->name, tcase->name) != 0) {
        old_testname = context->active_testname;
        context->active_testname = talloc_asprintf(context, "%s-%s", old_testname, test->name);
    }

    context->active_tcase = tcase;
    context->active_test = test;

    torture_ui_test_start(context, tcase, test);

    context->last_reason = NULL;
    context->last_result = TORTURE_OK;

    if (!already_setup && tcase->setup &&
            !tcase->setup(context, &(tcase->data))) {
        if (context->last_reason == NULL)
            context->last_reason = talloc_strdup(context, "Setup failure");
        context->last_result = TORTURE_ERROR;
        success = false;
    } else if (test->dangerous &&
               !torture_setting_bool(context, "dangerous", false)) {
        context->last_result = TORTURE_SKIP;
        context->last_reason = talloc_asprintf(context,
                                               "disabled %s - enable dangerous tests to use", test->name);
        success = true;
    } else {
        success = test->run(context, tcase, test);

        if (!success && context->last_result == TORTURE_OK) {
            if (context->last_reason == NULL)
                context->last_reason = talloc_strdup(context, "Unknown error/failure");
            context->last_result = TORTURE_ERROR;
        }
    }

    if (!already_setup && tcase->teardown && !tcase->teardown(context, tcase->data)) {
        if (context->last_reason == NULL)
            context->last_reason = talloc_strdup(context, "Setup failure");
        context->last_result = TORTURE_ERROR;
        success = false;
    }

    torture_ui_test_result(context, context->last_result,
                           context->last_reason);

    talloc_free(context->last_reason);

    if (tcase == NULL || strcmp(test->name, tcase->name) != 0) {
        talloc_free(context->active_testname);
        context->active_testname = old_testname;
    }
    context->active_test = NULL;
    context->active_tcase = NULL;

    return success;
}
Exemple #7
0
_PUBLIC_ struct test_join *torture_join_domain(struct torture_context *tctx,
					       const char *machine_name, 
				      uint32_t acct_flags,
				      struct cli_credentials **machine_credentials)
{
	NTSTATUS status;
	struct libnet_context *libnet_ctx;
	struct libnet_JoinDomain *libnet_r;
	struct test_join *tj;
	struct samr_SetUserInfo s;
	union samr_UserInfo u;
	const char *binding_str = NULL;
	struct dcerpc_binding *binding = NULL;
	enum dcerpc_transport_t transport;

	tj = talloc_zero(tctx, struct test_join);
	if (!tj) return NULL;

	binding_str = torture_setting_string(tctx, "binding", NULL);
	if (binding_str == NULL) {
		const char *host = torture_setting_string(tctx, "host", NULL);
		binding_str = talloc_asprintf(tj, "ncacn_np:%s", host);
	}
	status = dcerpc_parse_binding(tj, binding_str, &binding);
	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(0, ("dcerpc_parse_binding(%s) failed - %s\n",
			  binding_str, nt_errstr(status)));
		talloc_free(tj);
		return NULL;
	}
	transport = dcerpc_binding_get_transport(binding);
	switch (transport) {
	case NCALRPC:
	case NCACN_UNIX_STREAM:
		break;
	default:
		dcerpc_binding_set_transport(binding, NCACN_NP);
		dcerpc_binding_set_flags(binding, 0, DCERPC_AUTH_OPTIONS);
		break;
	}

	libnet_r = talloc_zero(tj, struct libnet_JoinDomain);
	if (!libnet_r) {
		talloc_free(tj);
		return NULL;
	}
	
	libnet_ctx = libnet_context_init(tctx->ev, tctx->lp_ctx);
	if (!libnet_ctx) {
		talloc_free(tj);
		return NULL;
	}
	
	tj->libnet_r = libnet_r;
		
	libnet_ctx->cred = cmdline_credentials;
	libnet_r->in.binding = dcerpc_binding_string(libnet_r, binding);
	if (libnet_r->in.binding == NULL) {
		talloc_free(tj);
		return NULL;
	}
	libnet_r->in.level = LIBNET_JOINDOMAIN_SPECIFIED;
	libnet_r->in.netbios_name = machine_name;
	libnet_r->in.account_name = talloc_asprintf(libnet_r, "%s$", machine_name);
	if (!libnet_r->in.account_name) {
		talloc_free(tj);
		return NULL;
	}
	
	libnet_r->in.acct_type = acct_flags;
	libnet_r->in.recreate_account = true;

	status = libnet_JoinDomain(libnet_ctx, libnet_r, libnet_r);
	if (!NT_STATUS_IS_OK(status)) {
		if (libnet_r->out.error_string) {
			DEBUG(0, ("Domain join failed - %s\n", libnet_r->out.error_string));
		} else {
			DEBUG(0, ("Domain join failed - %s\n", nt_errstr(status)));
		}
		talloc_free(tj);
                return NULL;
	}
	tj->p = libnet_r->out.samr_pipe;
	tj->user_handle = *libnet_r->out.user_handle;
	tj->dom_sid = libnet_r->out.domain_sid;
	talloc_steal(tj, libnet_r->out.domain_sid);
	tj->dom_netbios_name	= libnet_r->out.domain_name;
	talloc_steal(tj, libnet_r->out.domain_name);
	tj->dom_dns_name	= libnet_r->out.realm;
	talloc_steal(tj, libnet_r->out.realm);
	tj->user_guid = libnet_r->out.account_guid;
	tj->netbios_name = talloc_strdup(tj, machine_name);
	if (!tj->netbios_name) {
		talloc_free(tj);
		return NULL;
	}

	ZERO_STRUCT(u);
	s.in.user_handle = &tj->user_handle;
	s.in.info = &u;
	s.in.level = 21;

	u.info21.fields_present = SAMR_FIELD_DESCRIPTION | SAMR_FIELD_COMMENT | SAMR_FIELD_FULL_NAME;
	u.info21.comment.string = talloc_asprintf(tj, 
						  "Tortured by Samba4: %s", 
						  timestring(tj, time(NULL)));
	u.info21.full_name.string = talloc_asprintf(tj, 
						    "Torture account for Samba4: %s", 
						    timestring(tj, time(NULL)));
	
	u.info21.description.string = talloc_asprintf(tj, 
						      "Samba4 torture account created by host %s: %s", 
						      lpcfg_netbios_name(tctx->lp_ctx), timestring(tj, time(NULL)));

	status = dcerpc_samr_SetUserInfo_r(tj->p->binding_handle, tj, &s);
	if (!NT_STATUS_IS_OK(status)) {
		printf("SetUserInfo (non-critical) failed - %s\n", nt_errstr(status));
	}
	if (!NT_STATUS_IS_OK(s.out.result)) {
		printf("SetUserInfo (non-critical) failed - %s\n", nt_errstr(s.out.result));
	}

	*machine_credentials = cli_credentials_init(tj);
	cli_credentials_set_conf(*machine_credentials, tctx->lp_ctx);
	cli_credentials_set_workstation(*machine_credentials, machine_name, CRED_SPECIFIED);
	cli_credentials_set_domain(*machine_credentials, libnet_r->out.domain_name, CRED_SPECIFIED);
	if (libnet_r->out.realm) {
		cli_credentials_set_realm(*machine_credentials, libnet_r->out.realm, CRED_SPECIFIED);
	}
	cli_credentials_set_username(*machine_credentials, libnet_r->in.account_name, CRED_SPECIFIED);
	cli_credentials_set_password(*machine_credentials, libnet_r->out.join_password, CRED_SPECIFIED);
	cli_credentials_set_kvno(*machine_credentials, libnet_r->out.kvno);
	if (acct_flags & ACB_SVRTRUST) {
		cli_credentials_set_secure_channel_type(*machine_credentials,
							SEC_CHAN_BDC);
	} else if (acct_flags & ACB_WSTRUST) {
		cli_credentials_set_secure_channel_type(*machine_credentials,
							SEC_CHAN_WKSTA);
	} else {
		DEBUG(0, ("Invalid account type specificed to torture_join_domain\n"));
		talloc_free(*machine_credentials);
		return NULL;
	}

	return tj;
}
Exemple #8
0
const char *dcerpc_floor_get_rhs_data(TALLOC_CTX *mem_ctx, struct epm_floor *epm_floor)
{
	switch (epm_floor->lhs.protocol) {
	case EPM_PROTOCOL_TCP:
		if (epm_floor->rhs.tcp.port == 0) return NULL;
		return talloc_asprintf(mem_ctx, "%d", epm_floor->rhs.tcp.port);

	case EPM_PROTOCOL_UDP:
		if (epm_floor->rhs.udp.port == 0) return NULL;
		return talloc_asprintf(mem_ctx, "%d", epm_floor->rhs.udp.port);

	case EPM_PROTOCOL_HTTP:
		if (epm_floor->rhs.http.port == 0) return NULL;
		return talloc_asprintf(mem_ctx, "%d", epm_floor->rhs.http.port);

	case EPM_PROTOCOL_IP:
		return talloc_strdup(mem_ctx, epm_floor->rhs.ip.ipaddr);

	case EPM_PROTOCOL_NCACN:
		return NULL;

	case EPM_PROTOCOL_NCADG:
		return NULL;

	case EPM_PROTOCOL_SMB:
		if (strlen(epm_floor->rhs.smb.unc) == 0) return NULL;
		return talloc_strdup(mem_ctx, epm_floor->rhs.smb.unc);

	case EPM_PROTOCOL_NAMED_PIPE:
		if (strlen(epm_floor->rhs.named_pipe.path) == 0) return NULL;
		return talloc_strdup(mem_ctx, epm_floor->rhs.named_pipe.path);

	case EPM_PROTOCOL_NETBIOS:
		if (strlen(epm_floor->rhs.netbios.name) == 0) return NULL;
		return talloc_strdup(mem_ctx, epm_floor->rhs.netbios.name);

	case EPM_PROTOCOL_NCALRPC:
		return NULL;

	case EPM_PROTOCOL_VINES_SPP:
		return talloc_asprintf(mem_ctx, "%d", epm_floor->rhs.vines_spp.port);

	case EPM_PROTOCOL_VINES_IPC:
		return talloc_asprintf(mem_ctx, "%d", epm_floor->rhs.vines_ipc.port);

	case EPM_PROTOCOL_STREETTALK:
		return talloc_strdup(mem_ctx, epm_floor->rhs.streettalk.streettalk);

	case EPM_PROTOCOL_UNIX_DS:
		if (strlen(epm_floor->rhs.unix_ds.path) == 0) return NULL;
		return talloc_strdup(mem_ctx, epm_floor->rhs.unix_ds.path);

	case EPM_PROTOCOL_NULL:
		return NULL;

	default:
		DEBUG(0,("Unsupported lhs protocol %d\n", epm_floor->lhs.protocol));
		break;
	}

	return NULL;
}
Exemple #9
0
const char *epm_floor_string(TALLOC_CTX *mem_ctx, struct epm_floor *epm_floor)
{
	struct ndr_syntax_id syntax;
	NTSTATUS status;

	switch(epm_floor->lhs.protocol) {
		case EPM_PROTOCOL_UUID:
			status = dcerpc_floor_get_lhs_data(epm_floor, &syntax);
			if (NT_STATUS_IS_OK(status)) {
				/* lhs is used: UUID */
				char *uuidstr;

				if (GUID_equal(&syntax.uuid, &ndr_transfer_syntax_ndr.uuid)) {
					return "NDR";
				} 

				if (GUID_equal(&syntax.uuid, &ndr_transfer_syntax_ndr64.uuid)) {
					return "NDR64";
				} 

				uuidstr = GUID_string(mem_ctx, &syntax.uuid);

				return talloc_asprintf(mem_ctx, " uuid %s/0x%02x", uuidstr, syntax.if_version);
			} else { /* IPX */
				return talloc_asprintf(mem_ctx, "IPX:%s", 
						data_blob_hex_string_upper(mem_ctx, &epm_floor->rhs.uuid.unknown));
			}

		case EPM_PROTOCOL_NCACN:
			return "RPC-C";

		case EPM_PROTOCOL_NCADG:
			return "RPC";

		case EPM_PROTOCOL_NCALRPC:
			return "NCALRPC";

		case EPM_PROTOCOL_DNET_NSP:
			return "DNET/NSP";

		case EPM_PROTOCOL_IP:
			return talloc_asprintf(mem_ctx, "IP:%s", epm_floor->rhs.ip.ipaddr);

		case EPM_PROTOCOL_NAMED_PIPE:
			return talloc_asprintf(mem_ctx, "NAMED-PIPE:%s", epm_floor->rhs.named_pipe.path);

		case EPM_PROTOCOL_SMB:
			return talloc_asprintf(mem_ctx, "SMB:%s", epm_floor->rhs.smb.unc);

		case EPM_PROTOCOL_UNIX_DS:
			return talloc_asprintf(mem_ctx, "Unix:%s", epm_floor->rhs.unix_ds.path);

		case EPM_PROTOCOL_NETBIOS:
			return talloc_asprintf(mem_ctx, "NetBIOS:%s", epm_floor->rhs.netbios.name);

		case EPM_PROTOCOL_NETBEUI:
			return "NETBeui";

		case EPM_PROTOCOL_SPX:
			return "SPX";

		case EPM_PROTOCOL_NB_IPX:
			return "NB_IPX";

		case EPM_PROTOCOL_HTTP:
			return talloc_asprintf(mem_ctx, "HTTP:%d", epm_floor->rhs.http.port);

		case EPM_PROTOCOL_TCP:
			return talloc_asprintf(mem_ctx, "TCP:%d", epm_floor->rhs.tcp.port);

		case EPM_PROTOCOL_UDP:
			return talloc_asprintf(mem_ctx, "UDP:%d", epm_floor->rhs.udp.port);

		default:
			return talloc_asprintf(mem_ctx, "UNK(%02x):", epm_floor->lhs.protocol);
	}
}
Exemple #10
0
static WERROR cmd_drsuapi_getncchanges(struct rpc_pipe_client *cli,
				       TALLOC_CTX *mem_ctx, int argc,
				       const char **argv)
{
	NTSTATUS status;
	WERROR werr;

	struct policy_handle bind_handle;
	struct dcerpc_binding_handle *b = cli->binding_handle;

	struct GUID bind_guid;
	struct drsuapi_DsBindInfoCtr bind_info;
	struct drsuapi_DsBindInfo28 info28;

	const char *nc_dn = NULL;

	DATA_BLOB session_key;

	uint32_t level = 8;
	bool single = false;
	uint32_t level_out = 0;
	union drsuapi_DsGetNCChangesRequest req;
	union drsuapi_DsGetNCChangesCtr ctr;
	struct drsuapi_DsReplicaObjectIdentifier nc;
	struct dom_sid null_sid;

	struct drsuapi_DsGetNCChangesCtr1 *ctr1 = NULL;
	struct drsuapi_DsGetNCChangesCtr6 *ctr6 = NULL;
	uint32_t out_level = 0;
	int y;

	uint32_t supported_extensions = 0;
	uint32_t replica_flags	= DRSUAPI_DRS_WRIT_REP |
				  DRSUAPI_DRS_INIT_SYNC |
				  DRSUAPI_DRS_PER_SYNC |
				  DRSUAPI_DRS_GET_ANC |
				  DRSUAPI_DRS_NEVER_SYNCED;

	if (argc > 3) {
		printf("usage: %s [naming_context_or_object_dn [single]]\n", argv[0]);
		return WERR_OK;
	}

	if (argc >= 2) {
		nc_dn = argv[1];
	}

	if (argc == 3) {
		if (strequal(argv[2], "single")) {
			single = true;
		} else {
			printf("warning: ignoring unknown argument '%s'\n",
			       argv[2]);
		}
	}

	ZERO_STRUCT(info28);

	ZERO_STRUCT(null_sid);
	ZERO_STRUCT(req);

	GUID_from_string(DRSUAPI_DS_BIND_GUID, &bind_guid);

	info28.supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_BASE;
	info28.supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_ASYNC_REPLICATION;
	info28.supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_REMOVEAPI;
	info28.supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_MOVEREQ_V2;
	info28.supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_GETCHG_COMPRESS;
	info28.supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_DCINFO_V1;
	info28.supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_RESTORE_USN_OPTIMIZATION;
	info28.supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_KCC_EXECUTE;
	info28.supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_ADDENTRY_V2;
	info28.supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_LINKED_VALUE_REPLICATION;
	info28.supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_DCINFO_V2;
	info28.supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_INSTANCE_TYPE_NOT_REQ_ON_MOD;
	info28.supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_CRYPTO_BIND;
	info28.supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_GET_REPL_INFO;
	info28.supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_STRONG_ENCRYPTION;
	info28.supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_DCINFO_V01;
	info28.supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_TRANSITIVE_MEMBERSHIP;
	info28.supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_ADD_SID_HISTORY;
	info28.supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_POST_BETA3;
	info28.supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_GET_MEMBERSHIPS2;
	info28.supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_GETCHGREQ_V6;
	info28.supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_NONDOMAIN_NCS;
	info28.supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_GETCHGREQ_V8;
	info28.supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_GETCHGREPLY_V5;
	info28.supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_GETCHGREPLY_V6;
	info28.supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_ADDENTRYREPLY_V3;
	info28.supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_GETCHGREPLY_V7;
	info28.supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_VERIFY_OBJECT;
	info28.site_guid		= GUID_zero();
	info28.pid			= 0;
	info28.repl_epoch		= 0;

	bind_info.length = 28;
	bind_info.info.info28 = info28;

	status = dcerpc_drsuapi_DsBind(b, mem_ctx,
				       &bind_guid,
				       &bind_info,
				       &bind_handle,
				       &werr);

	if (!NT_STATUS_IS_OK(status)) {
		return ntstatus_to_werror(status);
	}

	if (!W_ERROR_IS_OK(werr)) {
		return werr;
	}

	if (bind_info.length == 24) {
		supported_extensions = bind_info.info.info24.supported_extensions;
	} else if (bind_info.length == 28) {
		supported_extensions = bind_info.info.info28.supported_extensions;
	} else if (bind_info.length == 48) {
		supported_extensions = bind_info.info.info48.supported_extensions;
	}

	if (!nc_dn) {

		union drsuapi_DsNameCtr crack_ctr;
		const char *name;

		name = talloc_asprintf(mem_ctx, "%s\\", lp_workgroup());
		W_ERROR_HAVE_NO_MEMORY(name);

		werr = cracknames(cli, mem_ctx,
				  &bind_handle,
				  DRSUAPI_DS_NAME_FORMAT_UNKNOWN,
				  DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
				  1,
				  &name,
				  &crack_ctr);
		if (!W_ERROR_IS_OK(werr)) {
			return werr;
		}

		if (crack_ctr.ctr1->count != 1) {
			return WERR_NO_SUCH_DOMAIN;
		}

		if (crack_ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
			return WERR_NO_SUCH_DOMAIN;
		}

		nc_dn = talloc_strdup(mem_ctx, crack_ctr.ctr1->array[0].result_name);
		W_ERROR_HAVE_NO_MEMORY(nc_dn);

		printf("using: %s\n", nc_dn);
	}

	nc.dn = nc_dn;
	nc.guid = GUID_zero();
	nc.sid = null_sid;

	if (supported_extensions & DRSUAPI_SUPPORTED_EXTENSION_GETCHGREQ_V8) {
		level = 8;
		req.req8.naming_context		= &nc;
		req.req8.replica_flags		= replica_flags;
		req.req8.max_object_count	= 402;
		req.req8.max_ndr_size		= 402116;
		if (single) {
			req.req8.extended_op	= DRSUAPI_EXOP_REPL_OBJ;
		}
	} else {
		level = 5;
		req.req5.naming_context		= &nc;
		req.req5.replica_flags		= replica_flags;
		req.req5.max_object_count	= 402;
		req.req5.max_ndr_size		= 402116;
		if (single) {
			req.req5.extended_op	= DRSUAPI_EXOP_REPL_OBJ;
		}
	}

	for (y=0; ;y++) {

		if (level == 8) {
			DEBUG(1,("start[%d] tmp_higest_usn: %llu , highest_usn: %llu\n",y,
				(long long)req.req8.highwatermark.tmp_highest_usn,
				(long long)req.req8.highwatermark.highest_usn));
		}

		status = dcerpc_drsuapi_DsGetNCChanges(b, mem_ctx,
						       &bind_handle,
						       level,
						       &req,
						       &level_out,
						       &ctr,
						       &werr);
		if (!NT_STATUS_IS_OK(status)) {
			werr = ntstatus_to_werror(status);
			printf("Failed to get NC Changes: %s",
				get_friendly_nt_error_msg(status));
			goto out;
		}

		if (!W_ERROR_IS_OK(werr)) {
			printf("Failed to get NC Changes: %s",
				get_friendly_werror_msg(werr));
			goto out;
		}

		if (level_out == 1) {
			out_level = 1;
			ctr1 = &ctr.ctr1;
		} else if (level_out == 2 && ctr.ctr2.mszip1.ts) {
			out_level = 1;
			ctr1 = &ctr.ctr2.mszip1.ts->ctr1;
		}

		status = cli_get_session_key(mem_ctx, cli, &session_key);
		if (!NT_STATUS_IS_OK(status)) {
			printf("Failed to get Session Key: %s",
				nt_errstr(status));
			return ntstatus_to_werror(status);
		}

		if (out_level == 1) {
			DEBUG(1,("end[%d] tmp_highest_usn: %llu , highest_usn: %llu\n",y,
				(long long)ctr1->new_highwatermark.tmp_highest_usn,
				(long long)ctr1->new_highwatermark.highest_usn));
#if 0
			libnet_dssync_decrypt_attributes(mem_ctx,
							 &session_key,
							 ctr1->first_object);
#endif
			if (ctr1->more_data) {
				req.req5.highwatermark = ctr1->new_highwatermark;
				continue;
			}
		}

		if (level_out == 6) {
			out_level = 6;
			ctr6 = &ctr.ctr6;
		} else if (level_out == 7
			   && ctr.ctr7.level == 6
			   && ctr.ctr7.type == DRSUAPI_COMPRESSION_TYPE_MSZIP
			   && ctr.ctr7.ctr.mszip6.ts) {
			out_level = 6;
			ctr6 = &ctr.ctr7.ctr.mszip6.ts->ctr6;
		} else if (level_out == 7
			   && ctr.ctr7.level == 6
			   && ctr.ctr7.type == DRSUAPI_COMPRESSION_TYPE_XPRESS
			   && ctr.ctr7.ctr.xpress6.ts) {
			out_level = 6;
			ctr6 = &ctr.ctr7.ctr.xpress6.ts->ctr6;
		}

		if (out_level == 6) {
			DEBUG(1,("end[%d] tmp_highest_usn: %llu , highest_usn: %llu\n",y,
				(long long)ctr6->new_highwatermark.tmp_highest_usn,
				(long long)ctr6->new_highwatermark.highest_usn));
#if 0
			libnet_dssync_decrypt_attributes(mem_ctx,
							 &session_key,
							 ctr6->first_object);
#endif
			if (ctr6->more_data) {
				req.req8.highwatermark = ctr6->new_highwatermark;
				continue;
			}
		}

		break;
	}

 out:
	return werr;
}
Exemple #11
0
/*
  form a binding string from a binding structure
*/
_PUBLIC_ char *dcerpc_binding_string(TALLOC_CTX *mem_ctx, const struct dcerpc_binding *b)
{
	char *s = talloc_strdup(mem_ctx, "");
	int i;
	const char *t_name = NULL;

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

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

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

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

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

	s = talloc_asprintf_append_buffer(s, "[");

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

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

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

	s = talloc_asprintf_append_buffer(s, "]");

	return s;
}
Exemple #12
0
/*
  test the TestSleep interface
*/
static bool test_sleep(struct torture_context *tctx,
						  struct dcerpc_pipe *p)
{
	int i;
	NTSTATUS status;
#define ASYNC_COUNT 3
	struct rpc_request *req[ASYNC_COUNT];
	struct echo_TestSleep r[ASYNC_COUNT];
	BOOL done[ASYNC_COUNT];
	struct timeval snd[ASYNC_COUNT];
	struct timeval rcv[ASYNC_COUNT];
	struct timeval diff[ASYNC_COUNT];
	struct event_context *ctx;
	int total_done = 0;

	if (torture_setting_bool(tctx, "quick", false)) {
		torture_skip(tctx, "TestSleep disabled - use \"torture:quick=no\" to enable\n");
	}
	torture_comment(tctx, "Testing TestSleep - use \"torture:quick=no\" to disable\n");

	for (i=0;i<ASYNC_COUNT;i++) {
		done[i]		= False;
		snd[i]		= timeval_current();
		rcv[i]		= timeval_zero();
		r[i].in.seconds = ASYNC_COUNT-i;
		req[i] = dcerpc_echo_TestSleep_send(p, tctx, &r[i]);
		torture_assert(tctx, req[i], "Failed to send async sleep request\n");
	}

	ctx = dcerpc_event_context(p);
	while (total_done < ASYNC_COUNT) {
		torture_assert(tctx, event_loop_once(ctx) == 0, 
					   "Event context loop failed");
		for (i=0;i<ASYNC_COUNT;i++) {
			if (done[i] == False && req[i]->state == RPC_REQUEST_DONE) {
				int rounded_tdiff;
				total_done++;
				done[i] = True;
				rcv[i]	= timeval_current();
				diff[i]	= timeval_until(&snd[i], &rcv[i]);
				rounded_tdiff = (int)(0.5 + diff[i].tv_sec + (1.0e-6*diff[i].tv_usec));
				status	= dcerpc_ndr_request_recv(req[i]);
				printf("rounded_tdiff=%d\n", rounded_tdiff);
				torture_assert_ntstatus_ok(tctx, status, 
							talloc_asprintf(tctx, "TestSleep(%d) failed", i));
				torture_assert(tctx, r[i].out.result == r[i].in.seconds,
					talloc_asprintf(tctx, "Failed - Asked to sleep for %u seconds (server replied with %u seconds and the reply takes only %u seconds)", 
					       	r[i].out.result, r[i].in.seconds, (uint_t)diff[i].tv_sec));
				torture_assert(tctx, r[i].out.result <= rounded_tdiff, 
					talloc_asprintf(tctx, "Failed - Slept for %u seconds (but reply takes only %u.%06u seconds)", 
						r[i].out.result, (uint_t)diff[i].tv_sec, (uint_t)diff[i].tv_usec));
				if (r[i].out.result+1 == rounded_tdiff) {
					torture_comment(tctx, "Slept for %u seconds (but reply takes %u.%06u seconds - busy server?)\n", 
							r[i].out.result, (uint_t)diff[i].tv_sec, (uint_t)diff[i].tv_usec);
				} else if (r[i].out.result == rounded_tdiff) {
					torture_comment(tctx, "Slept for %u seconds (reply takes %u.%06u seconds - ok)\n", 
							r[i].out.result, (uint_t)diff[i].tv_sec, (uint_t)diff[i].tv_usec);
				} else {
						torture_comment(tctx, "(Failed) - Not async - Slept for %u seconds (but reply takes %u.%06u seconds)", 
							r[i].out.result, (uint_t)diff[i].tv_sec, (uint_t)diff[i].tv_usec);
					/* TODO: let the test fail here, when we support async rpc on ncacn_np */
				}
			}
		}
	}
	return true;
}
Exemple #13
0
/**
   \details Test the NspiResolveNames and NspiResolveNamesW RPC
   operations (0x13 and 0x14)

   \param mt pointer on the top-level mapitest structure
   
   \return true on success, otherwise false
 */
_PUBLIC_ bool mapitest_nspi_ResolveNames(struct mapitest *mt)
{
	enum MAPISTATUS			retval;
	struct SPropTagArray		*SPropTagArray = NULL;
	struct PropertyRowSet_r		*RowSet = NULL;
	struct PropertyTagArray_r	*flaglist = NULL;
	const char			*username[2];
	const char     			*username_err[2];

	/* Build the username array */
	username[0] = (const char *)mt->profile->mailbox;
	username[1] = NULL;
	/* Build the err username array */
	username_err[0] = talloc_asprintf(mt->mem_ctx, "%s%s", mt->info.szDNPrefix, "nspi_resolve_testcase");
	username_err[1] = NULL;

	SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0xd,
					  PR_ENTRYID,
					  PR_DISPLAY_NAME,
					  PR_ADDRTYPE,
					  PR_GIVEN_NAME,
					  PR_SMTP_ADDRESS,
					  PR_OBJECT_TYPE,
					  PR_DISPLAY_TYPE,
					  PR_EMAIL_ADDRESS,
					  PR_SEND_INTERNET_ENCODING,
					  PR_SEND_RICH_INFO,
					  PR_SEARCH_KEY,
					  PR_TRANSMITTABLE_DISPLAY_NAME,
					  PR_7BIT_DISPLAY_NAME);

	/* Test with existing username */
	/* NspiResolveNames (0x13) */
	retval = ResolveNames(mt->session, (const char **)username, SPropTagArray, &RowSet, &flaglist, 0);
	mapitest_print_retval_clean(mt, "NspiResolveNames - existing", retval);
	if (retval != MAPI_E_SUCCESS) {
		MAPIFreeBuffer(SPropTagArray);
		return false;
	}
	if ( ! flaglist) {
		mapitest_print(mt, "\tNULL flaglist, which wasn't expected\n");
		MAPIFreeBuffer(SPropTagArray);
		return false;
	}
	if (flaglist->aulPropTag[0] != MAPI_RESOLVED) {
		mapitest_print(mt, "Expected 2 (MAPI_RESOLVED), but NspiResolveNames returned: %i\n", flaglist->aulPropTag[0]);
	} else {
		mapitest_print(mt, "\tGot expected resolution flag\n");
	}
	talloc_free(flaglist);
	talloc_free(RowSet);

	/* NspiResolveNamesW (0x14) */
	retval = ResolveNames(mt->session, (const char **)username, SPropTagArray, &RowSet, &flaglist, MAPI_UNICODE);
	mapitest_print_retval_clean(mt, "NspiResolveNamesW - existing", retval);
	if (flaglist->aulPropTag[0] != MAPI_RESOLVED) {
		mapitest_print(mt, "Expected 2 (MAPI_RESOLVED), but NspiResolveNamesW returned: %i\n", flaglist->aulPropTag[0]);
	} else {
		mapitest_print(mt, "\tGot expected resolution flag\n");
	}
	talloc_free(flaglist);
	talloc_free(RowSet);
	if (retval != MAPI_E_SUCCESS) {
		MAPIFreeBuffer(SPropTagArray);
		return false;
	}

	/* Test with non-existant username */
	/* NspiResolveNames (0x13) */
	retval = ResolveNames(mt->session, (const char **)username_err, SPropTagArray, &RowSet, &flaglist, 0);
	mapitest_print_retval_clean(mt, "NspiResolveNames - non existant user name", retval);
	if (flaglist->aulPropTag[0] != MAPI_UNRESOLVED) {
		mapitest_print(mt, "Expected 0 (MAPI_UNRESOLVED), but NspiResolveNames returned: %i\n", flaglist->aulPropTag[0]);
	} else {
		mapitest_print(mt, "\tGot expected resolution flag\n");
	}
	talloc_free(flaglist);
	talloc_free(RowSet);
	if (retval != MAPI_E_SUCCESS) {
		MAPIFreeBuffer(SPropTagArray);
		return false;
	}

	/* NspiResolveNamesW (0x14) */
	retval = ResolveNames(mt->session, (const char **)username_err, SPropTagArray, &RowSet, &flaglist, MAPI_UNICODE);
	mapitest_print_retval_clean(mt, "NspiResolveNamesW - non existant user name", retval);
	if (flaglist->aulPropTag[0] != MAPI_UNRESOLVED) {
		mapitest_print(mt, "Expected 0 (MAPI_UNRESOLVED), but NspiResolveNamesW returned: %i\n", flaglist->aulPropTag[0]);
	} else {
		mapitest_print(mt, "\tGot expected resolution flag\n");
	}
	talloc_free(flaglist);
	talloc_free(RowSet);
	if (retval != MAPI_E_SUCCESS) {
		MAPIFreeBuffer(SPropTagArray);
		return false;
	}
	MAPIFreeBuffer(SPropTagArray);
	return true;
}
Exemple #14
0
NTSTATUS unix_convert(TALLOC_CTX *ctx,
		      connection_struct *conn,
		      const char *orig_path,
		      struct smb_filename **smb_fname_out,
		      uint32_t ucf_flags)
{
	struct smb_filename *smb_fname = NULL;
	char *start, *end;
	char *dirpath = NULL;
	char *stream = NULL;
	bool component_was_mangled = False;
	bool name_has_wildcard = False;
	bool posix_pathnames = false;
	bool allow_wcard_last_component =
	    (ucf_flags & UCF_ALWAYS_ALLOW_WCARD_LCOMP);
	bool save_last_component = ucf_flags & UCF_SAVE_LCOMP;
	NTSTATUS status;
	int ret = -1;

	*smb_fname_out = NULL;

	smb_fname = talloc_zero(ctx, struct smb_filename);
	if (smb_fname == NULL) {
		return NT_STATUS_NO_MEMORY;
	}

	if (conn->printer) {
		/* we don't ever use the filenames on a printer share as a
			filename - so don't convert them */
		if (!(smb_fname->base_name = talloc_strdup(smb_fname,
							   orig_path))) {
			status = NT_STATUS_NO_MEMORY;
			goto err;
		}
		goto done;
	}

	DEBUG(5, ("unix_convert called on file \"%s\"\n", orig_path));

	/*
	 * Conversion to basic unix format is already done in
	 * check_path_syntax().
	 */

	/*
	 * Names must be relative to the root of the service - any leading /.
	 * and trailing /'s should have been trimmed by check_path_syntax().
	 */

#ifdef DEVELOPER
	SMB_ASSERT(*orig_path != '/');
#endif

	/*
	 * If we trimmed down to a single '\0' character
	 * then we should use the "." directory to avoid
	 * searching the cache, but not if we are in a
	 * printing share.
	 * As we know this is valid we can return true here.
	 */

	if (!*orig_path) {
		if (!(smb_fname->base_name = talloc_strdup(smb_fname, "."))) {
			status = NT_STATUS_NO_MEMORY;
			goto err;
		}
		if (SMB_VFS_STAT(conn, smb_fname) != 0) {
			status = map_nt_error_from_unix(errno);
			goto err;
		}
		DEBUG(5, ("conversion finished \"\" -> %s\n",
			  smb_fname->base_name));
		goto done;
	}

	if (orig_path[0] == '.' && (orig_path[1] == '/' ||
				orig_path[1] == '\0')) {
		/* Start of pathname can't be "." only. */
		if (orig_path[1] == '\0' || orig_path[2] == '\0') {
			status = NT_STATUS_OBJECT_NAME_INVALID;
		} else {
			status =determine_path_error(&orig_path[2],
			    allow_wcard_last_component);
		}
		goto err;
	}

	/* Start with the full orig_path as given by the caller. */
	if (!(smb_fname->base_name = talloc_strdup(smb_fname, orig_path))) {
		DEBUG(0, ("talloc_strdup failed\n"));
		status = NT_STATUS_NO_MEMORY;
		goto err;
	}

	/*
	 * Large directory fix normalization. If we're case sensitive, and
	 * the case preserving parameters are set to "no", normalize the case of
	 * the incoming filename from the client WHETHER IT EXISTS OR NOT !
	 * This is in conflict with the current (3.0.20) man page, but is
	 * what people expect from the "large directory howto". I'll update
	 * the man page. Thanks to [email protected] for finding this. JRA.
	 */

	if (conn->case_sensitive && !conn->case_preserve &&
			!conn->short_case_preserve) {
		strnorm(smb_fname->base_name, lp_defaultcase(SNUM(conn)));
	}

	/*
	 * Ensure saved_last_component is valid even if file exists.
	 */

	if(save_last_component) {
		end = strrchr_m(smb_fname->base_name, '/');
		if (end) {
			smb_fname->original_lcomp = talloc_strdup(smb_fname,
								  end + 1);
		} else {
			smb_fname->original_lcomp =
			    talloc_strdup(smb_fname, smb_fname->base_name);
		}
		if (smb_fname->original_lcomp == NULL) {
			status = NT_STATUS_NO_MEMORY;
			goto err;
		}
	}

	posix_pathnames = (lp_posix_pathnames() ||
				(ucf_flags & UCF_POSIX_PATHNAMES));

	/*
	 * Strip off the stream, and add it back when we're done with the
	 * base_name.
	 */
	if (!posix_pathnames) {
		stream = strchr_m(smb_fname->base_name, ':');

		if (stream != NULL) {
			char *tmp = talloc_strdup(smb_fname, stream);
			if (tmp == NULL) {
				status = NT_STATUS_NO_MEMORY;
				goto err;
			}
			/*
			 * Since this is actually pointing into
			 * smb_fname->base_name this truncates base_name.
			 */
			*stream = '\0';
			stream = tmp;
		}
	}

	start = smb_fname->base_name;

	/*
	 * If we're providing case insensitive semantics or
	 * the underlying filesystem is case insensitive,
	 * then a case-normalized hit in the stat-cache is
	 * authoratitive. JRA.
	 *
	 * Note: We're only checking base_name.  The stream_name will be
	 * added and verified in build_stream_path().
	 */

	if((!conn->case_sensitive || !(conn->fs_capabilities &
				       FILE_CASE_SENSITIVE_SEARCH)) &&
	    stat_cache_lookup(conn, posix_pathnames, &smb_fname->base_name, &dirpath, &start,
			      &smb_fname->st)) {
		goto done;
	}

	/*
	 * Make sure "dirpath" is an allocated string, we use this for
	 * building the directories with talloc_asprintf and free it.
	 */

	if ((dirpath == NULL) && (!(dirpath = talloc_strdup(ctx,"")))) {
		DEBUG(0, ("talloc_strdup failed\n"));
		status = NT_STATUS_NO_MEMORY;
		goto err;
	}

	/*
	 * If we have a wildcard we must walk the path to
	 * find where the error is, even if case sensitive
	 * is true.
	 */

	name_has_wildcard = ms_has_wild(smb_fname->base_name);
	if (name_has_wildcard && !allow_wcard_last_component) {
		/* Wildcard not valid anywhere. */
		status = NT_STATUS_OBJECT_NAME_INVALID;
		goto fail;
	}

	DEBUG(5,("unix_convert begin: name = %s, dirpath = %s, start = %s\n",
		 smb_fname->base_name, dirpath, start));

	if (!name_has_wildcard) {
		/*
		 * stat the name - if it exists then we can add the stream back (if
		 * there was one) and be done!
		 */

		if (posix_pathnames) {
			ret = SMB_VFS_LSTAT(conn, smb_fname);
		} else {
			ret = SMB_VFS_STAT(conn, smb_fname);
		}

		if (ret == 0) {
			status = check_for_dot_component(smb_fname);
			if (!NT_STATUS_IS_OK(status)) {
				goto fail;
			}
			/* Add the path (not including the stream) to the cache. */
			stat_cache_add(orig_path, smb_fname->base_name,
				       conn->case_sensitive);
			DEBUG(5,("conversion of base_name finished %s -> %s\n",
				 orig_path, smb_fname->base_name));
			goto done;
		}

		/* Stat failed - ensure we don't use it. */
		SET_STAT_INVALID(smb_fname->st);

		if (errno == ENOENT) {
			/* Optimization when creating a new file - only
			   the last component doesn't exist. */
			status = check_parent_exists(ctx,
						conn,
						posix_pathnames,
						smb_fname,
						&dirpath,
						&start);
			if (!NT_STATUS_IS_OK(status)) {
				goto fail;
			}
		}

		/*
		 * A special case - if we don't have any wildcards or mangling chars and are case
		 * sensitive or the underlying filesystem is case insensitive then searching
		 * won't help.
		 */

		if ((conn->case_sensitive || !(conn->fs_capabilities &
					FILE_CASE_SENSITIVE_SEARCH)) &&
				!mangle_is_mangled(smb_fname->base_name, conn->params)) {

			status = check_for_dot_component(smb_fname);
			if (!NT_STATUS_IS_OK(status)) {
				goto fail;
			}

			/*
			 * The stat failed. Could be ok as it could be
 			 * a new file.
 			 */

			if (errno == ENOTDIR || errno == ELOOP) {
				status = NT_STATUS_OBJECT_PATH_NOT_FOUND;
				goto fail;
			} else if (errno == ENOENT) {
				/*
				 * Was it a missing last component ?
				 * or a missing intermediate component ?
				 */
				struct smb_filename parent_fname;
				const char *last_component = NULL;

				ZERO_STRUCT(parent_fname);
				if (!parent_dirname(ctx, smb_fname->base_name,
							&parent_fname.base_name,
							&last_component)) {
					status = NT_STATUS_NO_MEMORY;
					goto fail;
				}
				if (posix_pathnames) {
					ret = SMB_VFS_LSTAT(conn, &parent_fname);
				} else {
					ret = SMB_VFS_STAT(conn, &parent_fname);
				}
				if (ret == -1) {
					if (errno == ENOTDIR ||
							errno == ENOENT ||
							errno == ELOOP) {
						status = NT_STATUS_OBJECT_PATH_NOT_FOUND;
						goto fail;
					}
				}

				/*
				 * Missing last component is ok - new file.
				 * Also deal with permission denied elsewhere.
				 * Just drop out to done.
				 */
				goto done;
			}
		}
	} else {
		/*
		 * We have a wildcard in the pathname.
		 *
		 * Optimization for common case where the wildcard
		 * is in the last component and the client already
		 * sent the correct case.
		 */
		status = check_parent_exists(ctx,
					conn,
					posix_pathnames,
					smb_fname,
					&dirpath,
					&start);
		if (!NT_STATUS_IS_OK(status)) {
			goto fail;
		}
	}

	/*
	 * is_mangled() was changed to look at an entire pathname, not
	 * just a component. JRA.
	 */

	if (mangle_is_mangled(start, conn->params)) {
		component_was_mangled = True;
	}

	/*
	 * Now we need to recursively match the name against the real
	 * directory structure.
	 */

	/*
	 * Match each part of the path name separately, trying the names
	 * as is first, then trying to scan the directory for matching names.
	 */

	for (; start ; start = (end?end+1:(char *)NULL)) {
		/*
		 * Pinpoint the end of this section of the filename.
		 */
		/* mb safe. '/' can't be in any encoded char. */
		end = strchr(start, '/');

		/*
		 * Chop the name at this point.
		 */
		if (end) {
			*end = 0;
		}

		if (save_last_component) {
			TALLOC_FREE(smb_fname->original_lcomp);
			smb_fname->original_lcomp = talloc_strdup(smb_fname,
							end ? end + 1 : start);
			if (!smb_fname->original_lcomp) {
				DEBUG(0, ("talloc failed\n"));
				status = NT_STATUS_NO_MEMORY;
				goto err;
			}
		}

		/* The name cannot have a component of "." */

		if (ISDOT(start)) {
			if (!end)  {
				/* Error code at the end of a pathname. */
				status = NT_STATUS_OBJECT_NAME_INVALID;
			} else {
				status = determine_path_error(end+1,
						allow_wcard_last_component);
			}
			goto fail;
		}

		/* The name cannot have a wildcard if it's not
		   the last component. */

		name_has_wildcard = ms_has_wild(start);

		/* Wildcards never valid within a pathname. */
		if (name_has_wildcard && end) {
			status = NT_STATUS_OBJECT_NAME_INVALID;
			goto fail;
		}

		/* Skip the stat call if it's a wildcard end. */
		if (name_has_wildcard) {
			DEBUG(5,("Wildcard %s\n",start));
			goto done;
		}

		/*
		 * Check if the name exists up to this point.
		 */

		if (posix_pathnames) {
			ret = SMB_VFS_LSTAT(conn, smb_fname);
		} else {
			ret = SMB_VFS_STAT(conn, smb_fname);
		}

		if (ret == 0) {
			/*
			 * It exists. it must either be a directory or this must
			 * be the last part of the path for it to be OK.
			 */
			if (end && !S_ISDIR(smb_fname->st.st_ex_mode)) {
				/*
				 * An intermediate part of the name isn't
				 * a directory.
				 */
				DEBUG(5,("Not a dir %s\n",start));
				*end = '/';
				/*
				 * We need to return the fact that the
				 * intermediate name resolution failed. This
				 * is used to return an error of ERRbadpath
				 * rather than ERRbadfile. Some Windows
				 * applications depend on the difference between
				 * these two errors.
				 */
				status = NT_STATUS_OBJECT_PATH_NOT_FOUND;
				goto fail;
			}

		} else {
			char *found_name = NULL;

			/* Stat failed - ensure we don't use it. */
			SET_STAT_INVALID(smb_fname->st);

			/*
			 * Reset errno so we can detect
			 * directory open errors.
			 */
			errno = 0;

			/*
			 * Try to find this part of the path in the directory.
			 */

			if (name_has_wildcard ||
			    (get_real_filename(conn, dirpath, start,
					       talloc_tos(),
					       &found_name) == -1)) {
				char *unmangled;

				if (end) {
					/*
					 * An intermediate part of the name
					 * can't be found.
					 */
					DEBUG(5,("Intermediate not found %s\n",
							start));
					*end = '/';

					/*
					 * We need to return the fact that the
					 * intermediate name resolution failed.
					 * This is used to return an error of
					 * ERRbadpath rather than ERRbadfile.
					 * Some Windows applications depend on
					 * the difference between these two
					 * errors.
					 */

					/*
					 * ENOENT, ENOTDIR and ELOOP all map
					 * to NT_STATUS_OBJECT_PATH_NOT_FOUND
					 * in the filename walk.
					 */

					if (errno == ENOENT ||
							errno == ENOTDIR ||
							errno == ELOOP) {
						status =
						NT_STATUS_OBJECT_PATH_NOT_FOUND;
					}
					else {
						status =
						map_nt_error_from_unix(errno);
					}
					goto fail;
				}

				/*
				 * ENOENT/EACCESS are the only valid errors
				 * here. EACCESS needs handling here for
				 * "dropboxes", i.e. directories where users
				 * can only put stuff with permission -wx.
				 */
				if ((errno != 0) && (errno != ENOENT)
				    && (errno != EACCES)) {
					/*
					 * ENOTDIR and ELOOP both map to
					 * NT_STATUS_OBJECT_PATH_NOT_FOUND
					 * in the filename walk.
					 */
					if (errno == ENOTDIR ||
							errno == ELOOP) {
						status =
						NT_STATUS_OBJECT_PATH_NOT_FOUND;
					} else {
						status =
						map_nt_error_from_unix(errno);
					}
					goto fail;
				}

				/*
				 * Just the last part of the name doesn't exist.
				 * We need to strupper() or strlower() it as
				 * this conversion may be used for file creation
				 * purposes. Fix inspired by
				 * Thomas Neumann <*****@*****.**>.
				 */
				if (!conn->case_preserve ||
				    (mangle_is_8_3(start, False,
						   conn->params) &&
						 !conn->short_case_preserve)) {
					strnorm(start,
						lp_defaultcase(SNUM(conn)));
				}

				/*
				 * check on the mangled stack to see if we can
				 * recover the base of the filename.
				 */

				if (mangle_is_mangled(start, conn->params)
				    && mangle_lookup_name_from_8_3(ctx,
					    		start,
							&unmangled,
							conn->params)) {
					char *tmp;
					size_t start_ofs =
					    start - smb_fname->base_name;

					if (*dirpath != '\0') {
						tmp = talloc_asprintf(
							smb_fname, "%s/%s",
							dirpath, unmangled);
						TALLOC_FREE(unmangled);
					}
					else {
						tmp = unmangled;
					}
					if (tmp == NULL) {
						DEBUG(0, ("talloc failed\n"));
						status = NT_STATUS_NO_MEMORY;
						goto err;
					}
					TALLOC_FREE(smb_fname->base_name);
					smb_fname->base_name = tmp;
					start =
					    smb_fname->base_name + start_ofs;
					end = start + strlen(start);
				}

				DEBUG(5,("New file %s\n",start));
				goto done;
			}


			/*
			 * Restore the rest of the string. If the string was
			 * mangled the size may have changed.
			 */
			if (end) {
				char *tmp;
				size_t start_ofs =
				    start - smb_fname->base_name;

				if (*dirpath != '\0') {
					tmp = talloc_asprintf(smb_fname,
						"%s/%s/%s", dirpath,
						found_name, end+1);
				}
				else {
					tmp = talloc_asprintf(smb_fname,
						"%s/%s", found_name,
						end+1);
				}
				if (tmp == NULL) {
					DEBUG(0, ("talloc_asprintf failed\n"));
					status = NT_STATUS_NO_MEMORY;
					goto err;
				}
				TALLOC_FREE(smb_fname->base_name);
				smb_fname->base_name = tmp;
				start = smb_fname->base_name + start_ofs;
				end = start + strlen(found_name);
				*end = '\0';
			} else {
				char *tmp;
				size_t start_ofs =
				    start - smb_fname->base_name;

				if (*dirpath != '\0') {
					tmp = talloc_asprintf(smb_fname,
						"%s/%s", dirpath,
						found_name);
				} else {
					tmp = talloc_strdup(smb_fname,
						found_name);
				}
				if (tmp == NULL) {
					DEBUG(0, ("talloc failed\n"));
					status = NT_STATUS_NO_MEMORY;
					goto err;
				}
				TALLOC_FREE(smb_fname->base_name);
				smb_fname->base_name = tmp;
				start = smb_fname->base_name + start_ofs;

				/*
				 * We just scanned for, and found the end of
				 * the path. We must return a valid stat struct
				 * if it exists. JRA.
				 */

				if (posix_pathnames) {
					ret = SMB_VFS_LSTAT(conn, smb_fname);
				} else {
					ret = SMB_VFS_STAT(conn, smb_fname);
				}

				if (ret != 0) {
					SET_STAT_INVALID(smb_fname->st);
				}
			}

			TALLOC_FREE(found_name);
		} /* end else */

#ifdef DEVELOPER
		/*
		 * This sucks!
		 * We should never provide different behaviors
		 * depending on DEVELOPER!!!
		 */
		if (VALID_STAT(smb_fname->st)) {
			bool delete_pending;
			uint32_t name_hash;

			status = file_name_hash(conn,
					smb_fname_str_dbg(smb_fname),
					&name_hash);
			if (!NT_STATUS_IS_OK(status)) {
				goto fail;
			}

			get_file_infos(vfs_file_id_from_sbuf(conn,
							     &smb_fname->st),
				       name_hash,
				       &delete_pending, NULL);
			if (delete_pending) {
				status = NT_STATUS_DELETE_PENDING;
				goto fail;
			}
		}
#endif

		/*
		 * Add to the dirpath that we have resolved so far.
		 */

		if (*dirpath != '\0') {
			char *tmp = talloc_asprintf(ctx,
					"%s/%s", dirpath, start);
			if (!tmp) {
				DEBUG(0, ("talloc_asprintf failed\n"));
				status = NT_STATUS_NO_MEMORY;
				goto err;
			}
			TALLOC_FREE(dirpath);
			dirpath = tmp;
		}
		else {
			TALLOC_FREE(dirpath);
			if (!(dirpath = talloc_strdup(ctx,start))) {
				DEBUG(0, ("talloc_strdup failed\n"));
				status = NT_STATUS_NO_MEMORY;
				goto err;
			}
		}

		/*
		 * Cache the dirpath thus far. Don't cache a name with mangled
		 * or wildcard components as this can change the size.
		 */
		if(!component_was_mangled && !name_has_wildcard) {
			stat_cache_add(orig_path, dirpath,
					conn->case_sensitive);
		}

		/*
		 * Restore the / that we wiped out earlier.
		 */
		if (end) {
			*end = '/';
		}
	}

	/*
	 * Cache the full path. Don't cache a name with mangled or wildcard
	 * components as this can change the size.
	 */

	if(!component_was_mangled && !name_has_wildcard) {
		stat_cache_add(orig_path, smb_fname->base_name,
			       conn->case_sensitive);
	}

	/*
	 * The name has been resolved.
	 */

	DEBUG(5,("conversion finished %s -> %s\n", orig_path,
		 smb_fname->base_name));

 done:
	/* Add back the stream if one was stripped off originally. */
	if (stream != NULL) {
		smb_fname->stream_name = stream;

		/* Check path now that the base_name has been converted. */
		status = build_stream_path(ctx, conn, orig_path, smb_fname);
		if (!NT_STATUS_IS_OK(status)) {
			goto fail;
		}
	}
	TALLOC_FREE(dirpath);
	*smb_fname_out = smb_fname;
	return NT_STATUS_OK;
 fail:
	DEBUG(10, ("dirpath = [%s] start = [%s]\n", dirpath, start));
	if (*dirpath != '\0') {
		smb_fname->base_name = talloc_asprintf(smb_fname, "%s/%s",
						       dirpath, start);
	} else {
		smb_fname->base_name = talloc_strdup(smb_fname, start);
	}
	if (!smb_fname->base_name) {
		DEBUG(0, ("talloc_asprintf failed\n"));
		status = NT_STATUS_NO_MEMORY;
		goto err;
	}

	*smb_fname_out = smb_fname;
	TALLOC_FREE(dirpath);
	return status;
 err:
	TALLOC_FREE(smb_fname);
	return status;
}
Exemple #15
0
/*
  test a schannel connection with the given flags
 */
static BOOL test_schannel(TALLOC_CTX *mem_ctx, 
			  uint16_t acct_flags, uint32_t dcerpc_flags,
			  int i)
{
	BOOL ret = True;

	struct test_join *join_ctx;
	NTSTATUS status;
	const char *binding = lp_parm_string(-1, "torture", "binding");
	struct dcerpc_binding *b;
	struct dcerpc_pipe *p = NULL;
	struct dcerpc_pipe *p_netlogon = NULL;
	struct dcerpc_pipe *p_netlogon2 = NULL;
	struct dcerpc_pipe *p_netlogon3 = NULL;
	struct dcerpc_pipe *p_samr2 = NULL;
	struct dcerpc_pipe *p_lsa = NULL;
	struct creds_CredentialState *creds;
	struct cli_credentials *credentials;

	TALLOC_CTX *test_ctx = talloc_named(mem_ctx, 0, "test_schannel context");

	join_ctx = torture_join_domain(talloc_asprintf(mem_ctx, "%s%d", TEST_MACHINE_NAME, i), 
				       acct_flags, &credentials);
	if (!join_ctx) {
		printf("Failed to join domain with acct_flags=0x%x\n", acct_flags);
		talloc_free(test_ctx);
		return False;
	}

	status = dcerpc_parse_binding(test_ctx, binding, &b);
	if (!NT_STATUS_IS_OK(status)) {
		printf("Bad binding string %s\n", binding);
		goto failed;
	}

	b->flags &= ~DCERPC_AUTH_OPTIONS;
	b->flags |= dcerpc_flags;

	status = dcerpc_pipe_connect_b(test_ctx, &p, b, &dcerpc_table_samr,
				       credentials, NULL);
	if (!NT_STATUS_IS_OK(status)) {
		printf("Failed to connect with schannel: %s\n", nt_errstr(status));
		goto failed;
	}

	if (!test_samr_ops(p, test_ctx)) {
		printf("Failed to process schannel secured SAMR ops\n");
		ret = False;
	}

	/* Also test that when we connect to the netlogon pipe, that
	 * the credentials we setup on the first pipe are valid for
	 * the second */

	/* Swap the binding details from SAMR to NETLOGON */
	status = dcerpc_epm_map_binding(test_ctx, b, &dcerpc_table_netlogon, NULL);
	if (!NT_STATUS_IS_OK(status)) {
		goto failed;
	}

	status = dcerpc_secondary_connection(p, &p_netlogon, 
					     b);

	if (!NT_STATUS_IS_OK(status)) {
		goto failed;
	}

	status = dcerpc_bind_auth(p_netlogon, &dcerpc_table_netlogon,
				  credentials, DCERPC_AUTH_TYPE_SCHANNEL,
				  dcerpc_auth_level(p->conn),
				  NULL);

	if (!NT_STATUS_IS_OK(status)) {
		goto failed;
	}

	status = dcerpc_schannel_creds(p_netlogon->conn->security_state.generic_state, test_ctx, &creds);
	if (!NT_STATUS_IS_OK(status)) {
		goto failed;
	}

	/* do a couple of logins */
	if (!test_netlogon_ops(p_netlogon, test_ctx, credentials, creds)) {
		printf("Failed to process schannel secured NETLOGON ops\n");
		ret = False;
	}

	if (!test_netlogon_ex_ops(p_netlogon, test_ctx, credentials, creds)) {
		printf("Failed to process schannel secured NETLOGON EX ops\n");
		ret = False;
	}

	/* Swap the binding details from SAMR to LSARPC */
	status = dcerpc_epm_map_binding(test_ctx, b, &dcerpc_table_lsarpc, NULL);
	if (!NT_STATUS_IS_OK(status)) {
		goto failed;
	}

	status = dcerpc_secondary_connection(p, &p_lsa, 
					     b);

	if (!NT_STATUS_IS_OK(status)) {
		goto failed;
	}

	status = dcerpc_bind_auth(p_lsa, &dcerpc_table_lsarpc,
				  credentials, DCERPC_AUTH_TYPE_SCHANNEL,
				  dcerpc_auth_level(p->conn),
				  NULL);

	if (!NT_STATUS_IS_OK(status)) {
		goto failed;
	}

	if (!test_lsa_ops(p_lsa, test_ctx)) {
		printf("Failed to process schannel secured LSA ops\n");
		ret = False;
	}

	/* Drop the socket, we want to start from scratch */
	talloc_free(p);
	p = NULL;

	/* Now see what we are still allowed to do */
	
	status = dcerpc_parse_binding(test_ctx, binding, &b);
	if (!NT_STATUS_IS_OK(status)) {
		printf("Bad binding string %s\n", binding);
		goto failed;
	}

	b->flags &= ~DCERPC_AUTH_OPTIONS;
	b->flags |= dcerpc_flags;

	status = dcerpc_pipe_connect_b(test_ctx, &p_samr2, b, &dcerpc_table_samr,
				       credentials, NULL);
	if (!NT_STATUS_IS_OK(status)) {
		printf("Failed to connect with schannel: %s\n", nt_errstr(status));
		goto failed;
	}

	/* do a some SAMR operations.  We have *not* done a new serverauthenticate */
	if (!test_samr_ops(p_samr2, test_ctx)) {
		printf("Failed to process schannel secured SAMR ops (on fresh connection)\n");
		goto failed;
	}

	/* Swap the binding details from SAMR to NETLOGON */
	status = dcerpc_epm_map_binding(test_ctx, b, &dcerpc_table_netlogon, NULL);
	if (!NT_STATUS_IS_OK(status)) {
		goto failed;
	}

	status = dcerpc_secondary_connection(p_samr2, &p_netlogon2, 
					     b);
	if (!NT_STATUS_IS_OK(status)) {
		goto failed;
	}

	/* and now setup an SCHANNEL bind on netlogon */
	status = dcerpc_bind_auth(p_netlogon2, &dcerpc_table_netlogon,
				  credentials, DCERPC_AUTH_TYPE_SCHANNEL,
				  dcerpc_auth_level(p_samr2->conn),
				  NULL);

	if (!NT_STATUS_IS_OK(status)) {
		goto failed;
	}
	
	/* Try the schannel-only SamLogonEx operation */
	if (!test_netlogon_ex_ops(p_netlogon2, test_ctx, credentials, creds)) {
		printf("Failed to process schannel secured NETLOGON EX ops (on fresh connection)\n");
		ret = False;
	}

	/* And the more traditional style, proving that the
	 * credentials chaining state is fully present */
	if (!test_netlogon_ops(p_netlogon2, test_ctx, credentials, creds)) {
		printf("Failed to process schannel secured NETLOGON ops (on fresh connection)\n");
		ret = False;
	}

	/* Drop the socket, we want to start from scratch (again) */
	talloc_free(p_samr2);

	/* We don't want schannel for this test */
	b->flags &= ~DCERPC_AUTH_OPTIONS;

	status = dcerpc_pipe_connect_b(test_ctx, &p_netlogon3, b, &dcerpc_table_netlogon,
				       credentials, NULL);
	if (!NT_STATUS_IS_OK(status)) {
		printf("Failed to connect without schannel: %s\n", nt_errstr(status));
		goto failed;
	}

	if (test_netlogon_ex_ops(p_netlogon3, test_ctx, credentials, creds)) {
		printf("Processed NOT schannel secured NETLOGON EX ops without SCHANNEL (unsafe)\n");
		ret = False;
	}

	if (!test_netlogon_ops(p_netlogon3, test_ctx, credentials, creds)) {
		printf("Failed to processed NOT schannel secured NETLOGON ops without new ServerAuth\n");
		ret = False;
	}

	torture_leave_domain(join_ctx);
	talloc_free(test_ctx);
	return ret;

failed:
	torture_leave_domain(join_ctx);
	talloc_free(test_ctx);
	return False;	
}
Exemple #16
0
NTSTATUS gp_fetch_gpt (struct gp_context *gp_ctx, struct gp_object *gpo,
                       const char **ret_local_path)
{
	TALLOC_CTX *mem_ctx;
	struct gp_list_state *state;
	NTSTATUS status;
	struct stat st;
	int rv;
	const char *local_path, *share_path;

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

	if (gp_ctx->cli == NULL) {
		status = gp_cli_connect(gp_ctx);
		if (!NT_STATUS_IS_OK(status)) {
			DEBUG(0, ("Failed to create cli connection to DC\n"));
			talloc_free(mem_ctx);
			return status;
		}
	}

	/* Get the remote path to copy from */
	share_path = gp_get_share_path(mem_ctx, gpo->file_sys_path);
	NT_STATUS_HAVE_NO_MEMORY_AND_FREE(share_path, mem_ctx);

	/* Get the local path to copy to */
	local_path = talloc_asprintf(gp_ctx, "%s/%s", gp_tmpdir(mem_ctx), gpo->name);
	NT_STATUS_HAVE_NO_MEMORY_AND_FREE(local_path, mem_ctx);

	/* Prepare the state structure */
	state = talloc_zero(mem_ctx, struct gp_list_state);
	NT_STATUS_HAVE_NO_MEMORY_AND_FREE(state, mem_ctx);

	state->tree = gp_ctx->cli->tree;
	state->share_path = share_path;

	/* Create the GPO dir if it does not exist */
	if (stat(local_path, &st) != 0) {
		rv = mkdir(local_path, 0755);
		if (rv < 0) {
			DEBUG(0, ("Could not create local path\n"));
			talloc_free(mem_ctx);
			return NT_STATUS_UNSUCCESSFUL;
		}
	}

	/* Get the file list */
	status = gp_do_list("", state);
	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(0, ("Could not list GPO files on remote server\n"));
		talloc_free(mem_ctx);
		return status;
	}

	/* If the list has no entries there is a problem. */
	if (state->list.num_files == 0) {
		DEBUG(0, ("File list is has no entries. Is the GPT directory empty?\n"));
		talloc_free(mem_ctx);
		return NT_STATUS_UNSUCCESSFUL;
	}

	/* Fetch the files */
	status = gp_get_files(gp_ctx->cli->tree, share_path, local_path, &state->list);

	/* Return the local path to the gpo */
	*ret_local_path = local_path;

	talloc_free(mem_ctx);
	return NT_STATUS_OK;
}
Exemple #17
0
/*
  try a netlogon SamLogon
*/
BOOL test_netlogon_ex_ops(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
			  struct cli_credentials *credentials, 
			  struct creds_CredentialState *creds)
{
	NTSTATUS status;
	struct netr_LogonSamLogonEx r;
	struct netr_NetworkInfo ninfo;
	DATA_BLOB names_blob, chal, lm_resp, nt_resp;
	int i;
	BOOL ret = True;
	int flags = CLI_CRED_NTLM_AUTH;
	if (lp_client_lanman_auth()) {
		flags |= CLI_CRED_LANMAN_AUTH;
	}

	if (lp_client_ntlmv2_auth()) {
		flags |= CLI_CRED_NTLMv2_AUTH;
	}

	cli_credentials_get_ntlm_username_domain(cmdline_credentials, mem_ctx, 
						 &ninfo.identity_info.account_name.string,
						 &ninfo.identity_info.domain_name.string);
	
	generate_random_buffer(ninfo.challenge, 
			       sizeof(ninfo.challenge));
	chal = data_blob_const(ninfo.challenge, 
			       sizeof(ninfo.challenge));

	names_blob = NTLMv2_generate_names_blob(mem_ctx, cli_credentials_get_workstation(credentials), 
						cli_credentials_get_domain(credentials));

	status = cli_credentials_get_ntlm_response(cmdline_credentials, mem_ctx, 
						   &flags, 
						   chal,
						   names_blob,
						   &lm_resp, &nt_resp,
						   NULL, NULL);
	if (!NT_STATUS_IS_OK(status)) {
		printf("cli_credentials_get_ntlm_response failed: %s\n", 
		       nt_errstr(status));
		return False;
	}

	ninfo.lm.data = lm_resp.data;
	ninfo.lm.length = lm_resp.length;

	ninfo.nt.data = nt_resp.data;
	ninfo.nt.length = nt_resp.length;

	ninfo.identity_info.parameter_control = 0;
	ninfo.identity_info.logon_id_low = 0;
	ninfo.identity_info.logon_id_high = 0;
	ninfo.identity_info.workstation.string = cli_credentials_get_workstation(credentials);

	r.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
	r.in.computer_name = cli_credentials_get_workstation(credentials);
	r.in.logon_level = 2;
	r.in.logon.network = &ninfo;
	r.in.flags = 0;

	printf("Testing LogonSamLogonEx with name %s\n", ninfo.identity_info.account_name.string);
	
	for (i=2;i<3;i++) {
		r.in.validation_level = i;
		
		status = dcerpc_netr_LogonSamLogonEx(p, mem_ctx, &r);
		if (!NT_STATUS_IS_OK(status)) {
			printf("LogonSamLogon failed: %s\n", 
			       nt_errstr(status));
			return False;
		}
	}

	return ret;
}
Exemple #18
0
static NTSTATUS push_recursive (struct gp_context *gp_ctx, const char *local_path,
                                const char *remote_path, int depth)
{
	DIR *dir;
	struct dirent *dirent;
	char *entry_local_path;
	char *entry_remote_path;
	int local_fd, remote_fd;
	int buf[1024];
	int nread, total_read;
	struct stat s;

	dir = opendir(local_path);
	while ((dirent = readdir(dir)) != NULL) {
		if (strcmp(dirent->d_name, ".") == 0 ||
				strcmp(dirent->d_name, "..") == 0) {
			continue;
		}

		entry_local_path = talloc_asprintf(gp_ctx, "%s/%s", local_path,
		                                   dirent->d_name);
		NT_STATUS_HAVE_NO_MEMORY(entry_local_path);

		entry_remote_path = talloc_asprintf(gp_ctx, "%s\\%s",
		                                    remote_path, dirent->d_name);
		NT_STATUS_HAVE_NO_MEMORY(entry_remote_path);

		if (stat(dirent->d_name, &s) != 0) {
			return NT_STATUS_UNSUCCESSFUL;
		}
		if (s.st_mode & S_IFDIR) {
			DEBUG(6, ("Pushing directory %s to %s on sysvol\n",
			          entry_local_path, entry_remote_path));
			smbcli_mkdir(gp_ctx->cli->tree, entry_remote_path);
			if (depth < GP_MAX_DEPTH) {
				push_recursive(gp_ctx, entry_local_path,
				               entry_remote_path, depth+1);
			}
		} else {
			DEBUG(6, ("Pushing file %s to %s on sysvol\n",
			          entry_local_path, entry_remote_path));
			remote_fd = smbcli_open(gp_ctx->cli->tree,
			                        entry_remote_path,
			                        O_WRONLY | O_CREAT,
			                        0);
			if (remote_fd < 0) {
				talloc_free(entry_local_path);
				talloc_free(entry_remote_path);
				DEBUG(0, ("Failed to create remote file: %s\n",
				          entry_remote_path));
				return NT_STATUS_UNSUCCESSFUL;
			}
			local_fd = open(entry_local_path, O_RDONLY);
			if (local_fd < 0) {
				talloc_free(entry_local_path);
				talloc_free(entry_remote_path);
				DEBUG(0, ("Failed to open local file: %s\n",
				          entry_local_path));
				return NT_STATUS_UNSUCCESSFUL;
			}
			total_read = 0;
			while ((nread = read(local_fd, &buf, sizeof(buf)))) {
				smbcli_write(gp_ctx->cli->tree, remote_fd, 0,
						&buf, total_read, nread);
				total_read += nread;
			}

			close(local_fd);
			smbcli_close(gp_ctx->cli->tree, remote_fd);
		}
		talloc_free(entry_local_path);
		talloc_free(entry_remote_path);
	}
	closedir(dir);

	return NT_STATUS_OK;
}
Exemple #19
0
struct test_join *torture_create_testuser_max_pwlen(struct torture_context *torture,
						    const char *username,
						    const char *domain,
						    uint16_t acct_type,
						    const char **random_password,
						    int max_pw_len)
{
	NTSTATUS status;
	struct samr_Connect c;
	struct samr_CreateUser2 r;
	struct samr_OpenDomain o;
	struct samr_LookupDomain l;
	struct dom_sid2 *sid = NULL;
	struct samr_GetUserPwInfo pwp;
	struct samr_PwInfo info;
	struct samr_SetUserInfo s;
	union samr_UserInfo u;
	struct policy_handle handle;
	uint32_t access_granted;
	uint32_t rid;
	DATA_BLOB session_key;
	struct lsa_String name;
	
	int policy_min_pw_len = 0;
	struct test_join *join;
	char *random_pw;
	const char *dc_binding = torture_setting_string(torture, "dc_binding", NULL);
	struct dcerpc_binding_handle *b = NULL;

	join = talloc(NULL, struct test_join);
	if (join == NULL) {
		return NULL;
	}

	ZERO_STRUCTP(join);

	printf("Connecting to SAMR\n");
	
	if (dc_binding) {
		status = dcerpc_pipe_connect(join,
					     &join->p,
					     dc_binding,
					     &ndr_table_samr,
					     cmdline_credentials, NULL, torture->lp_ctx);
					     
	} else {
		status = torture_rpc_connection(torture, 
						&join->p, 
						&ndr_table_samr);
	}
	if (!NT_STATUS_IS_OK(status)) {
		return NULL;
	}
	b = join->p->binding_handle;

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

	status = dcerpc_samr_Connect_r(b, join, &c);
	if (!NT_STATUS_IS_OK(status)) {
		const char *errstr = nt_errstr(status);
		printf("samr_Connect failed - %s\n", errstr);
		return NULL;
	}
	if (!NT_STATUS_IS_OK(c.out.result)) {
		const char *errstr = nt_errstr(c.out.result);
		printf("samr_Connect failed - %s\n", errstr);
		return NULL;
	}

	if (domain) {
		printf("Opening domain %s\n", domain);

		name.string = domain;
		l.in.connect_handle = &handle;
		l.in.domain_name = &name;
		l.out.sid = &sid;

		status = dcerpc_samr_LookupDomain_r(b, join, &l);
		if (!NT_STATUS_IS_OK(status)) {
			printf("LookupDomain failed - %s\n", nt_errstr(status));
			goto failed;
		}
		if (!NT_STATUS_IS_OK(l.out.result)) {
			printf("LookupDomain failed - %s\n", nt_errstr(l.out.result));
			goto failed;
		}
	} else {
		struct samr_EnumDomains e;
		uint32_t resume_handle = 0, num_entries;
		struct samr_SamArray *sam;
		int i;

		e.in.connect_handle = &handle;
		e.in.buf_size = (uint32_t)-1;
		e.in.resume_handle = &resume_handle;
		e.out.sam = &sam;
		e.out.num_entries = &num_entries;
		e.out.resume_handle = &resume_handle;

		status = dcerpc_samr_EnumDomains_r(b, join, &e);
		if (!NT_STATUS_IS_OK(status)) {
			printf("EnumDomains failed - %s\n", nt_errstr(status));
			goto failed;
		}
		if (!NT_STATUS_IS_OK(e.out.result)) {
			printf("EnumDomains failed - %s\n", nt_errstr(e.out.result));
			goto failed;
		}
		if ((num_entries != 2) || (sam && sam->count != 2)) {
			printf("unexpected number of domains\n");
			goto failed;
		}
		for (i=0; i < 2; i++) {
			if (!strequal(sam->entries[i].name.string, "builtin")) {
				domain = sam->entries[i].name.string;
				break;
			}
		}
		if (domain) {
			printf("Opening domain %s\n", domain);

			name.string = domain;
			l.in.connect_handle = &handle;
			l.in.domain_name = &name;
			l.out.sid = &sid;

			status = dcerpc_samr_LookupDomain_r(b, join, &l);
			if (!NT_STATUS_IS_OK(status)) {
				printf("LookupDomain failed - %s\n", nt_errstr(status));
				goto failed;
			}
			if (!NT_STATUS_IS_OK(l.out.result)) {
				printf("LookupDomain failed - %s\n", nt_errstr(l.out.result));
				goto failed;
			}
		} else {
			printf("cannot proceed without domain name\n");
			goto failed;
		}
	}

	talloc_steal(join, *l.out.sid);
	join->dom_sid = *l.out.sid;
	join->dom_netbios_name = talloc_strdup(join, domain);
	if (!join->dom_netbios_name) goto failed;

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

	status = dcerpc_samr_OpenDomain_r(b, join, &o);
	if (!NT_STATUS_IS_OK(status)) {
		printf("OpenDomain failed - %s\n", nt_errstr(status));
		goto failed;
	}
	if (!NT_STATUS_IS_OK(o.out.result)) {
		printf("OpenDomain failed - %s\n", nt_errstr(o.out.result));
		goto failed;
	}

	printf("Creating account %s\n", username);

again:
	name.string = username;
	r.in.domain_handle = &join->domain_handle;
	r.in.account_name = &name;
	r.in.acct_flags = acct_type;
	r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
	r.out.user_handle = &join->user_handle;
	r.out.access_granted = &access_granted;
	r.out.rid = &rid;

	status = dcerpc_samr_CreateUser2_r(b, join, &r);
	if (!NT_STATUS_IS_OK(status)) {
		printf("CreateUser2 failed - %s\n", nt_errstr(status));
		goto failed;
	}

	if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_USER_EXISTS)) {
		status = DeleteUser_byname(b, join, &join->domain_handle, name.string);
		if (NT_STATUS_IS_OK(status)) {
			goto again;
		}
	}

	if (!NT_STATUS_IS_OK(r.out.result)) {
		printf("CreateUser2 failed - %s\n", nt_errstr(r.out.result));
		goto failed;
	}

	join->user_sid = dom_sid_add_rid(join, join->dom_sid, rid);

	pwp.in.user_handle = &join->user_handle;
	pwp.out.info = &info;

	status = dcerpc_samr_GetUserPwInfo_r(b, join, &pwp);
	if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(pwp.out.result)) {
		policy_min_pw_len = pwp.out.info->min_password_length;
	}

	random_pw = generate_random_password(join, MAX(8, policy_min_pw_len), max_pw_len);

	printf("Setting account password '%s'\n", random_pw);

	ZERO_STRUCT(u);
	s.in.user_handle = &join->user_handle;
	s.in.info = &u;
	s.in.level = 24;

	encode_pw_buffer(u.info24.password.data, random_pw, STR_UNICODE);
	u.info24.password_expired = 0;

	status = dcerpc_fetch_session_key(join->p, &session_key);
	if (!NT_STATUS_IS_OK(status)) {
		printf("SetUserInfo level %u - no session key - %s\n",
		       s.in.level, nt_errstr(status));
		torture_leave_domain(torture, join);
		goto failed;
	}

	arcfour_crypt_blob(u.info24.password.data, 516, &session_key);

	status = dcerpc_samr_SetUserInfo_r(b, join, &s);
	if (!NT_STATUS_IS_OK(status)) {
		printf("SetUserInfo failed - %s\n", nt_errstr(status));
		goto failed;
	}
	if (!NT_STATUS_IS_OK(s.out.result)) {
		printf("SetUserInfo failed - %s\n", nt_errstr(s.out.result));
		goto failed;
	}

	ZERO_STRUCT(u);
	s.in.user_handle = &join->user_handle;
	s.in.info = &u;
	s.in.level = 21;

	u.info21.acct_flags = acct_type | ACB_PWNOEXP;
	u.info21.fields_present = SAMR_FIELD_ACCT_FLAGS | SAMR_FIELD_DESCRIPTION | SAMR_FIELD_COMMENT | SAMR_FIELD_FULL_NAME;

	u.info21.comment.string = talloc_asprintf(join, 
						  "Tortured by Samba4: %s", 
						  timestring(join, time(NULL)));
	
	u.info21.full_name.string = talloc_asprintf(join, 
						    "Torture account for Samba4: %s", 
						    timestring(join, time(NULL)));
	
	u.info21.description.string = talloc_asprintf(join, 
					 "Samba4 torture account created by host %s: %s", 
					 lpcfg_netbios_name(torture->lp_ctx),
					 timestring(join, time(NULL)));

	printf("Resetting ACB flags, force pw change time\n");

	status = dcerpc_samr_SetUserInfo_r(b, join, &s);
	if (!NT_STATUS_IS_OK(status)) {
		printf("SetUserInfo failed - %s\n", nt_errstr(status));
		goto failed;
	}
	if (!NT_STATUS_IS_OK(s.out.result)) {
		printf("SetUserInfo failed - %s\n", nt_errstr(s.out.result));
		goto failed;
	}

	if (random_password) {
		*random_password = random_pw;
	}

	return join;

failed:
	torture_leave_domain(torture, join);
	return NULL;
}
Exemple #20
0
NTSTATUS gp_create_gpt(struct gp_context *gp_ctx, const char *name,
                       const char *file_sys_path)
{
	TALLOC_CTX *mem_ctx;
	const char *tmp_dir, *policy_dir, *tmp_str;
	int rv;
	int fd;
	NTSTATUS status;
	const char *file_content = "[General]\r\nVersion=0\r\n";

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

	tmp_dir = gp_tmpdir(mem_ctx);
	NT_STATUS_HAVE_NO_MEMORY(tmp_dir);
	policy_dir = talloc_asprintf(mem_ctx, "%s/%s", tmp_dir, name);
	NT_STATUS_HAVE_NO_MEMORY(policy_dir);

	/* Create the directories */

	rv = mkdir(policy_dir, 0755);
	if (rv < 0) {
		DEBUG(0, ("Could not create the policy dir: %s\n", policy_dir));
		talloc_free(mem_ctx);
		return NT_STATUS_UNSUCCESSFUL;
	}

	tmp_str = talloc_asprintf(mem_ctx, "%s/User", policy_dir);
	NT_STATUS_HAVE_NO_MEMORY(tmp_str);
	rv = mkdir(tmp_str, 0755);
	if (rv < 0) {
		DEBUG(0, ("Could not create the User dir: %s\n", tmp_str));
		talloc_free(mem_ctx);
		return NT_STATUS_UNSUCCESSFUL;
	}

	tmp_str = talloc_asprintf(mem_ctx, "%s/Machine", policy_dir);
	NT_STATUS_HAVE_NO_MEMORY(tmp_str);
	rv = mkdir(tmp_str, 0755);
	if (rv < 0) {
		DEBUG(0, ("Could not create the Machine dir: %s\n", tmp_str));
		talloc_free(mem_ctx);
		return NT_STATUS_UNSUCCESSFUL;
	}

	/* Create a GPT.INI with version 0 */

	tmp_str = talloc_asprintf(mem_ctx, "%s/GPT.INI", policy_dir);
	NT_STATUS_HAVE_NO_MEMORY(tmp_str);
	fd = open(tmp_str, O_CREAT | O_WRONLY, 0644);
	if (fd < 0) {
		DEBUG(0, ("Could not create the GPT.INI: %s\n", tmp_str));
		talloc_free(mem_ctx);
		return NT_STATUS_UNSUCCESSFUL;
	}

	rv = write(fd, file_content, strlen(file_content));
	if (rv != strlen(file_content)) {
		DEBUG(0, ("Short write in GPT.INI\n"));
		talloc_free(mem_ctx);
		return NT_STATUS_UNSUCCESSFUL;
	}

	close(fd);

	/* Upload the GPT to the sysvol share on a DC */
	status = gp_push_gpt(gp_ctx, policy_dir, file_sys_path);
	if (!NT_STATUS_IS_OK(status)) {
		talloc_free(mem_ctx);
		return status;
	}

	talloc_free(mem_ctx);
	return NT_STATUS_OK;
}
Exemple #21
0
static NTSTATUS torture_leave_ads_domain(struct torture_context *torture,
					 TALLOC_CTX *mem_ctx,
					 struct libnet_JoinDomain *libnet_r)
{
	int rtn;
	TALLOC_CTX *tmp_ctx;

	struct ldb_dn *server_dn;
	struct ldb_context *ldb_ctx;

	char *remote_ldb_url; 
	 
	/* Check if we are a domain controller. If not, exit. */
	if (!libnet_r->out.server_dn_str) {
		return NT_STATUS_OK;
	}

	tmp_ctx = talloc_named(mem_ctx, 0, "torture_leave temporary context");
	if (!tmp_ctx) {
		libnet_r->out.error_string = NULL;
		return NT_STATUS_NO_MEMORY;
	}

	ldb_ctx = ldb_init(tmp_ctx, torture->ev);
	if (!ldb_ctx) {
		libnet_r->out.error_string = NULL;
		talloc_free(tmp_ctx);
		return NT_STATUS_NO_MEMORY;
	}

	/* Remove CN=Servers,... entry from the AD. */ 
	server_dn = ldb_dn_new(tmp_ctx, ldb_ctx, libnet_r->out.server_dn_str);
	if (! ldb_dn_validate(server_dn)) {
		libnet_r->out.error_string = NULL;
		talloc_free(tmp_ctx);
		return NT_STATUS_NO_MEMORY;
	}

	remote_ldb_url = talloc_asprintf(tmp_ctx, "ldap://%s",
		dcerpc_binding_get_string_option(libnet_r->out.samr_binding, "host"));
	if (!remote_ldb_url) {
		libnet_r->out.error_string = NULL;
		talloc_free(tmp_ctx);
		return NT_STATUS_NO_MEMORY;
	}

	ldb_set_opaque(ldb_ctx, "credentials", cmdline_credentials);
	ldb_set_opaque(ldb_ctx, "loadparm", cmdline_lp_ctx);

	rtn = ldb_connect(ldb_ctx, remote_ldb_url, 0, NULL);
	if (rtn != LDB_SUCCESS) {
		libnet_r->out.error_string = NULL;
		talloc_free(tmp_ctx);
		return NT_STATUS_UNSUCCESSFUL;
	}

	rtn = ldb_delete(ldb_ctx, server_dn);
	if (rtn != LDB_SUCCESS) {
		libnet_r->out.error_string = NULL;
		talloc_free(tmp_ctx);
		return NT_STATUS_UNSUCCESSFUL;
	}

	DEBUG(0, ("%s removed successfully.\n", libnet_r->out.server_dn_str));

	talloc_free(tmp_ctx); 
	return NT_STATUS_OK;
}
/**
   \details Add a scenario parsed from configuration file to the list
   of available scenarios

   \param ctx pointer to the openchangesim context
   \param gscenario pointer to the current generic scenario record to
   be added

   \return OCSIM_SUCCESS on success, otherwise OCSIM_ERROR
 */
_PUBLIC_ int configuration_add_scenario(struct ocsim_context *ctx,
					struct ocsim_generic_scenario *gscenario)
{
	struct ocsim_scenario	*el;
	int			i, j;

	/* Sanity checks */
	OCSIM_RETVAL_IF(!ctx, OCSIM_ERROR, OCSIM_NOT_INITIALIZED, NULL);
	OCSIM_RETVAL_IF(!gscenario, OCSIM_ERROR, OCSIM_INVALID_PARAMETER, NULL);

	if (!gscenario->name) {
		DEBUG(0, (DEBUG_FORMAT_STRING_ERR, DEBUG_ERR_MISSING_NAME));
		return OCSIM_ERROR;
	}

	/* Ensure the scenario has not already been added */
	if (configuration_validate_scenario(ctx, gscenario->name)) {
		DEBUG(0, (DEBUG_FORMAT_STRING_MODULE_ERR, gscenario->name, DEBUG_ERR_DUPLICATE));
		return OCSIM_ERROR;
	}
	

	if (!strcasecmp(gscenario->name, SENDMAIL_MODULE_NAME)) {
		struct ocsim_scenario_sendmail		*sendmail;
		struct ocsim_scenario_case		*element;
		struct ocsim_generic_scenario_case	*elm;

		el = talloc_zero(ctx->mem_ctx, struct ocsim_scenario);
		el->cases = NULL;
		el->name = talloc_strdup(el, gscenario->name);
		el->repeat = gscenario->repeat;

		for (elm = gscenario->case_el, j = 0; elm; elm = elm->next, j++) {
			element = talloc_zero(el, struct ocsim_scenario_case);
			sendmail = talloc_zero(element, struct ocsim_scenario_sendmail);
			
			sendmail->body_type = elm->body_type;
			switch (sendmail->body_type) {
			case OCSIM_BODY_NONE:
				sendmail->body_inline = NULL;
				sendmail->body_file = NULL;
				break;
			case OCSIM_BODY_UTF8_INLINE:
			case OCSIM_BODY_HTML_INLINE:
				sendmail->body_inline = talloc_strdup(sendmail, elm->body_inline);
				break;
			case OCSIM_BODY_UTF8_FILE:
			case OCSIM_BODY_HTML_FILE:
			case OCSIM_BODY_RTF_FILE:
				sendmail->body_file = talloc_strdup(sendmail, elm->body_file);
				break;
			}
			sendmail->attachment_count = elm->attachment_count;
			sendmail->attachments = talloc_array(sendmail, char *, sendmail->attachment_count + 2);
			for (i = 0; i < sendmail->attachment_count; i++) {
				sendmail->attachments[i] = talloc_strdup(sendmail->attachments, elm->attachments[i]);
			}
			if (elm->name) {
				element->name = talloc_strdup(element, elm->name);
			}  else {
				element->name = talloc_asprintf(element, "scenario case %d", j);
			}
			element->private_data = (void *) sendmail;
			DLIST_ADD_END(el->cases, element, struct ocsim_scenario_case);
		}		

		DLIST_ADD_END(ctx->scenarios, el, struct ocsim_scenario *);

	} else if (!strcasecmp(gscenario->name, FETCHMAIL_MODULE_NAME)) {
Exemple #23
0
NSS_STATUS _nss_ldb_initgroups_dyn(const char *user, gid_t group, long int *start, long int *size, gid_t **groups, long int limit, int *errnop)
{
    int ret;
    char *filter;
    const char * attrs[] = { "uidNumber", "gidNumber", NULL };
    struct ldb_result *uid_res;
    struct ldb_result *mem_res;

    ret = _ldb_nss_init();
    if (ret != NSS_STATUS_SUCCESS) {
        return ret;
    }

    mem_res = talloc_zero(_ldb_nss_ctx, struct ldb_result);
    if ( ! mem_res) {
        errno = *errnop = ENOMEM;
        return NSS_STATUS_UNAVAIL;
    }

    /* build the filter for this name */
    filter = talloc_asprintf(mem_res, _LDB_NSS_PWNAM_FILTER, user);
    if (filter == NULL) {
        /* this is a fatal error */
        *errnop = errno = ENOENT;
        ret = NSS_STATUS_UNAVAIL;
        goto done;
    }

    /* search the entry */
    ret = ldb_search(_ldb_nss_ctx->ldb,
                     _ldb_nss_ctx->base,
                     LDB_SCOPE_SUBTREE,
                     filter,
                     attrs,
                     &uid_res);
    if (ret != LDB_SUCCESS) {
        /* this is a fatal error */
        *errnop = errno = ENOENT;
        ret = NSS_STATUS_UNAVAIL;
        goto done;
    }

    talloc_steal(mem_res, uid_res);

    /* if none found return */
    if (uid_res->count == 0) {
        *errnop = errno = ENOENT;
        ret = NSS_STATUS_NOTFOUND;
        goto done;
    }

    if (uid_res->count != 1) {
        /* this is a fatal error */
        *errnop = errno = ENOENT;
        ret = NSS_STATUS_UNAVAIL;
        goto done;
    }

    ret = _ldb_nss_group_request(&mem_res,
                                 uid_res->msgs[0]->dn,
                                 attrs,
                                 "memberOf");

    if (ret != NSS_STATUS_SUCCESS) {
        *errnop = errno;
        goto done;
    }

    ret = _ldb_nss_fill_initgr(group,
                               limit,
                               start,
                               size,
                               groups,
                               errnop,
                               mem_res);

    if (ret != NSS_STATUS_SUCCESS) {
        goto done;
    }

    ret = NSS_STATUS_SUCCESS;

done:
    talloc_free(mem_res);
    return ret;
}
Exemple #24
0
WERROR spoolss_create_default_devmode(TALLOC_CTX *mem_ctx,
				      const char *devicename,
				      struct spoolss_DeviceMode **devmode)
{
	struct spoolss_DeviceMode *dm;
	char *dname;

	dm = talloc_zero(mem_ctx, struct spoolss_DeviceMode);
	if (dm == NULL) {
		return WERR_NOMEM;
	}

	dname = talloc_asprintf(dm, "%s", devicename);
	if (dname == NULL) {
		return WERR_NOMEM;
	}
	if (strlen(dname) > MAXDEVICENAME) {
		dname[MAXDEVICENAME] = '\0';
	}
	dm->devicename = dname;

	dm->formname = talloc_strdup(dm, "Letter");
	if (dm->formname == NULL) {
		return WERR_NOMEM;
	}

	dm->specversion          = DMSPEC_NT4_AND_ABOVE;
	dm->driverversion        = 0x0400;
	dm->size                 = 0x00DC;
	dm->__driverextra_length = 0;
	dm->fields               = DEVMODE_FORMNAME |
				   DEVMODE_TTOPTION |
				   DEVMODE_PRINTQUALITY |
				   DEVMODE_DEFAULTSOURCE |
				   DEVMODE_COPIES |
				   DEVMODE_SCALE |
				   DEVMODE_PAPERSIZE |
				   DEVMODE_ORIENTATION;
	dm->orientation          = DMORIENT_PORTRAIT;
	dm->papersize            = DMPAPER_LETTER;
	dm->paperlength          = 0;
	dm->paperwidth           = 0;
	dm->scale                = 0x64;
	dm->copies               = 1;
	dm->defaultsource        = DMBIN_FORMSOURCE;
	dm->printquality         = DMRES_HIGH;           /* 0x0258 */
	dm->color                = DMRES_MONOCHROME;
	dm->duplex               = DMDUP_SIMPLEX;
	dm->yresolution          = 0;
	dm->ttoption             = DMTT_SUBDEV;
	dm->collate              = DMCOLLATE_FALSE;
	dm->icmmethod            = 0;
	dm->icmintent            = 0;
	dm->mediatype            = 0;
	dm->dithertype           = 0;

	dm->logpixels            = 0;
	dm->bitsperpel           = 0;
	dm->pelswidth            = 0;
	dm->pelsheight           = 0;
	dm->displayflags         = 0;
	dm->displayfrequency     = 0;
	dm->reserved1            = 0;
	dm->reserved2            = 0;
	dm->panningwidth         = 0;
	dm->panningheight        = 0;

	dm->driverextra_data.data = NULL;
	dm->driverextra_data.length = 0;

        *devmode = dm;
	return WERR_OK;
}
WERROR gp_reg_state_read(TALLOC_CTX *mem_ctx,
			 uint32_t flags,
			 const DOM_SID *sid,
			 struct GROUP_POLICY_OBJECT **gpo_list)
{
	struct gp_registry_context *reg_ctx = NULL;
	WERROR werr = WERR_GENERAL_FAILURE;
	const char *subkeyname = NULL;
	struct GROUP_POLICY_OBJECT *gpo = NULL;
	int count = 0;
	struct registry_key *key = NULL;
	const char *path = NULL;
	const char *gp_state_path = NULL;

	if (!gpo_list) {
		return WERR_INVALID_PARAM;
	}

	ZERO_STRUCTP(gpo_list);

	gp_state_path = gp_req_state_path(mem_ctx, sid, flags);
	if (!gp_state_path) {
		werr = WERR_NOMEM;
		goto done;
	}

	path = talloc_asprintf(mem_ctx, "%s\\%s\\%s",
			       KEY_GROUP_POLICY,
			       gp_state_path,
			       "GPO-List");
	if (!path) {
		werr = WERR_NOMEM;
		goto done;
	}

	werr = gp_init_reg_ctx(mem_ctx, path, REG_KEY_READ, NULL, &reg_ctx);
	if (!W_ERROR_IS_OK(werr)) {
		goto done;
	}

	while (1) {

		subkeyname = talloc_asprintf(mem_ctx, "%d", count++);
		if (!subkeyname) {
			werr = WERR_NOMEM;
			goto done;
		}

		werr = gp_read_reg_subkey(mem_ctx, reg_ctx, subkeyname, &key);
		if (W_ERROR_EQUAL(werr, WERR_BADFILE)) {
			werr = WERR_OK;
			break;
		}
		if (!W_ERROR_IS_OK(werr)) {
			DEBUG(0,("gp_reg_state_read: "
				"gp_read_reg_subkey gave: %s\n",
				dos_errstr(werr)));
			goto done;
		}

		werr = gp_read_reg_gpo(mem_ctx, key, &gpo);
		if (!W_ERROR_IS_OK(werr)) {
			goto done;
		}

		DLIST_ADD(*gpo_list, gpo);
	}

 done:
	gp_free_reg_ctx(reg_ctx);
	return werr;
}
Exemple #26
0
NTSTATUS samba3_read_regdb ( const char *fn, TALLOC_CTX *ctx, struct samba3_regdb *db )
{
    uint32_t vers_id;
    TDB_CONTEXT *tdb;
    TDB_DATA kbuf, vbuf;

    /* placeholder tdb; reinit upon startup */

    if ( !(tdb = tdb_open(fn, 0, TDB_DEFAULT, O_RDONLY, 0600)) )
    {
        DEBUG(0, ("Unable to open registry database %s\n", fn));
        return NT_STATUS_UNSUCCESSFUL;
    }

    vers_id = tdb_fetch_int32(tdb, "INFO/version");

    db->key_count = 0;
    db->keys = NULL;

    if (vers_id != -1 && vers_id >= REGVER_V1) {
        DEBUG(0, ("Registry version mismatch: %d\n", vers_id));
        return NT_STATUS_UNSUCCESSFUL;
    }

    for (kbuf = tdb_firstkey(tdb); kbuf.dptr; kbuf = tdb_nextkey(tdb, kbuf))
    {
        uint32_t len;
        int i;
        struct samba3_regkey key;
        char *skey;

        if (strncmp((char *)kbuf.dptr, VALUE_PREFIX, strlen(VALUE_PREFIX)) == 0)
            continue;

        vbuf = tdb_fetch(tdb, kbuf);

        key.name = talloc_strdup(ctx, (char *)kbuf.dptr);

        len = tdb_unpack(tdb, (char *)vbuf.dptr, vbuf.dsize, "d", &key.subkey_count);

        key.value_count = 0;
        key.values = NULL;
        key.subkeys = talloc_array(ctx, char *, key.subkey_count);

        for (i = 0; i < key.subkey_count; i++) {
            fstring tmp;
            len += tdb_unpack( tdb, (char *)vbuf.dptr+len, vbuf.dsize-len, "f", tmp );
            key.subkeys[i] = talloc_strdup(ctx, tmp);
        }

        skey = talloc_asprintf(ctx, "%s/%s", VALUE_PREFIX, kbuf.dptr );

        vbuf = tdb_fetch_bystring( tdb, skey );

        if ( vbuf.dptr ) {
            regdb_unpack_values( tdb, ctx, &key, vbuf );
        }

        db->keys = talloc_realloc(ctx, db->keys, struct samba3_regkey, db->key_count+1);
        db->keys[db->key_count] = key;
        db->key_count++;
    }

    tdb_close(tdb);

    return NT_STATUS_OK;
}
Exemple #27
0
/* convert a single name to a sid in a domain */
NTSTATUS rpc_name_to_sid(TALLOC_CTX *mem_ctx,
			 struct rpc_pipe_client *lsa_pipe,
			 struct policy_handle *lsa_policy,
			 const char *domain_name,
			 const char *name,
			 uint32_t flags,
			 struct dom_sid *sid,
			 enum lsa_SidType *type)
{
	enum lsa_SidType *types = NULL;
	struct dom_sid *sids = NULL;
	char *full_name = NULL;
	char *mapped_name = NULL;
	NTSTATUS status;

	if (name == NULL || name[0] == '\0') {
		full_name = talloc_asprintf(mem_ctx, "%s", domain_name);
	} else if (domain_name == NULL || domain_name[0] == '\0') {
		full_name = talloc_asprintf(mem_ctx, "%s", name);
	} else {
		full_name = talloc_asprintf(mem_ctx, "%s\\%s", domain_name, name);
	}

	if (full_name == NULL) {
		return NT_STATUS_NO_MEMORY;
	}

	status = normalize_name_unmap(mem_ctx, full_name, &mapped_name);
	/* Reset the full_name pointer if we mapped anything */
	if (NT_STATUS_IS_OK(status) ||
	    NT_STATUS_EQUAL(status, NT_STATUS_FILE_RENAMED)) {
		full_name = mapped_name;
	}

	DEBUG(3,("name_to_sid: %s for domain %s\n",
		 full_name ? full_name : "", domain_name ));

	/*
	 * We don't run into deadlocks here, cause winbind_off() is
	 * called in the main function.
	 */
	status = rpccli_lsa_lookup_names(lsa_pipe,
					 mem_ctx,
					 lsa_policy,
					 1, /* num_names */
					 (const char **) &full_name,
					 NULL, /* domains */
					 1, /* level */
					 &sids,
					 &types);
	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(2,("name_to_sid: failed to lookup name: %s\n",
			nt_errstr(status)));
		return status;
	}

	sid_copy(sid, &sids[0]);
	*type = types[0];

	return NT_STATUS_OK;
}
Exemple #28
0
static bool lookup_name_from_8_3(TALLOC_CTX *ctx,
				const char *in,
				char **out, /* talloced on the given context. */
				const struct share_params *p)
{
	TDB_DATA data_val;
	char *saved_ext = NULL;
	char *s = talloc_strdup(ctx, in);
	char magic_char;

	magic_char = lp_magicchar(p);

	/* If the cache isn't initialized, give up. */
	if(!s || !tdb_mangled_cache ) {
		TALLOC_FREE(s);
		return False;
	}

	data_val = tdb_fetch_bystring(tdb_mangled_cache, s);

	/* If we didn't find the name *with* the extension, try without. */
	if(data_val.dptr == NULL || data_val.dsize == 0) {
		char *ext_start = strrchr( s, '.' );
		if( ext_start ) {
			if((saved_ext = talloc_strdup(ctx,ext_start)) == NULL) {
				TALLOC_FREE(s);
				return False;
			}

			*ext_start = '\0';
			data_val = tdb_fetch_bystring(tdb_mangled_cache, s);
			/*
			 * At this point s is the name without the
			 * extension. We re-add the extension if saved_ext
			 * is not null, before freeing saved_ext.
			 */
		}
	}

	/* Okay, if we haven't found it we're done. */
	if(data_val.dptr == NULL || data_val.dsize == 0) {
		TALLOC_FREE(saved_ext);
		TALLOC_FREE(s);
		return False;
	}

	/* If we *did* find it, we need to talloc it on the given ctx. */
	if (saved_ext) {
		*out = talloc_asprintf(ctx, "%s%s",
					(char *)data_val.dptr,
					saved_ext);
	} else {
		*out = talloc_strdup(ctx, (char *)data_val.dptr);
	}

	TALLOC_FREE(s);
	TALLOC_FREE(saved_ext);
	SAFE_FREE(data_val.dptr);

	return *out ? True : False;
}
Exemple #29
0
/*
  startup the kcc service task
*/
static void kccsrv_task_init(struct task_server *task)
{
	WERROR status;
	struct kccsrv_service *service;
	uint32_t periodic_startup_interval;

	switch (lp_server_role(task->lp_ctx)) {
	case ROLE_STANDALONE:
		task_server_terminate(task, "kccsrv: no KCC required in standalone configuration", false);
		return;
	case ROLE_DOMAIN_MEMBER:
		task_server_terminate(task, "kccsrv: no KCC required in domain member configuration", false);
		return;
	case ROLE_DOMAIN_CONTROLLER:
		/* Yes, we want a KCC */
		break;
	}

	task_server_set_title(task, "task[kccsrv]");

	service = talloc_zero(task, struct kccsrv_service);
	if (!service) {
		task_server_terminate(task, "kccsrv_task_init: out of memory", true);
		return;
	}
	service->task		= task;
	service->startup_time	= timeval_current();
	task->private_data	= service;

	status = kccsrv_init_creds(service);
	if (!W_ERROR_IS_OK(status)) {
		task_server_terminate(task, 
				      talloc_asprintf(task,
						      "kccsrv: Failed to obtain server credentials: %s\n",
						      win_errstr(status)), true);
		return;
	}

	status = kccsrv_connect_samdb(service, task->lp_ctx);
	if (!W_ERROR_IS_OK(status)) {
		task_server_terminate(task, talloc_asprintf(task,
				      "kccsrv: Failed to connect to local samdb: %s\n",
							    win_errstr(status)), true);
		return;
	}

	status = kccsrv_load_partitions(service);
	if (!W_ERROR_IS_OK(status)) {
		task_server_terminate(task, talloc_asprintf(task,
				      "kccsrv: Failed to load partitions: %s\n",
							    win_errstr(status)), true);
		return;
	}

	periodic_startup_interval	= lp_parm_int(task->lp_ctx, NULL, "kccsrv", 
						      "periodic_startup_interval", 15); /* in seconds */
	service->periodic.interval	= lp_parm_int(task->lp_ctx, NULL, "kccsrv", 
						      "periodic_interval", 300); /* in seconds */

	status = kccsrv_periodic_schedule(service, periodic_startup_interval);
	if (!W_ERROR_IS_OK(status)) {
		task_server_terminate(task, talloc_asprintf(task,
				      "kccsrv: Failed to periodic schedule: %s\n",
							    win_errstr(status)), true);
		return;
	}

	irpc_add_name(task->msg_ctx, "kccsrv");
	IRPC_REGISTER(task->msg_ctx, drsuapi, DRSUAPI_DSEXECUTEKCC, kccsrv_execute_kcc, service);
}
Exemple #30
0
bool torture_samba3_badpath(struct torture_context *torture)
{
	struct smbcli_state *cli_nt;
	struct smbcli_state *cli_dos;
	const char *fname = "test.txt";
	const char *fname1 = "test1.txt";
	const char *dirname = "testdir";
	char *fpath;
	char *fpath1;
	int fnum;
	NTSTATUS status;
	bool ret = true;
	TALLOC_CTX *mem_ctx;
	bool nt_status_support;

	if (!(mem_ctx = talloc_init("torture_samba3_badpath"))) {
		d_printf("talloc_init failed\n");
		return false;
	}

	nt_status_support = lp_nt_status_support(torture->lp_ctx);

	if (!lp_set_cmdline(torture->lp_ctx, "nt status support", "yes")) {
		printf("Could not set 'nt status support = yes'\n");
		goto fail;
	}

	if (!torture_open_connection(&cli_nt, torture, 0)) {
		goto fail;
	}

	if (!lp_set_cmdline(torture->lp_ctx, "nt status support", "no")) {
		printf("Could not set 'nt status support = yes'\n");
		goto fail;
	}

	if (!torture_open_connection(&cli_dos, torture, 1)) {
		goto fail;
	}

	if (!lp_set_cmdline(torture->lp_ctx, "nt status support",
			    nt_status_support ? "yes":"no")) {
		printf("Could not reset 'nt status support = yes'");
		goto fail;
	}

	smbcli_deltree(cli_nt->tree, dirname);

	status = smbcli_mkdir(cli_nt->tree, dirname);
	if (!NT_STATUS_IS_OK(status)) {
		d_printf("smbcli_mkdir failed: %s\n", nt_errstr(status));
		ret = false;
		goto done;
	}

	status = smbcli_chkpath(cli_nt->tree, dirname);
	CHECK_STATUS(status, NT_STATUS_OK);

	status = smbcli_chkpath(cli_nt->tree,
				talloc_asprintf(mem_ctx, "%s\\bla", dirname));
	CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);

	status = smbcli_chkpath(cli_dos->tree,
				talloc_asprintf(mem_ctx, "%s\\bla", dirname));
	CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS, ERRbadpath));

	status = smbcli_chkpath(cli_nt->tree,
				talloc_asprintf(mem_ctx, "%s\\bla\\blub",
						dirname));
	CHECK_STATUS(status, NT_STATUS_OBJECT_PATH_NOT_FOUND);
	status = smbcli_chkpath(cli_dos->tree,
				talloc_asprintf(mem_ctx, "%s\\bla\\blub",
						dirname));
	CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS, ERRbadpath));

	if (!(fpath = talloc_asprintf(mem_ctx, "%s\\%s", dirname, fname))) {
		goto fail;
	}
	fnum = smbcli_open(cli_nt->tree, fpath, O_RDWR | O_CREAT, DENY_NONE);
	if (fnum == -1) {
		d_printf("Could not create file %s: %s\n", fpath,
			 smbcli_errstr(cli_nt->tree));
		goto fail;
	}
	smbcli_close(cli_nt->tree, fnum);

	if (!(fpath1 = talloc_asprintf(mem_ctx, "%s\\%s", dirname, fname1))) {
		goto fail;
	}
	fnum = smbcli_open(cli_nt->tree, fpath1, O_RDWR | O_CREAT, DENY_NONE);
	if (fnum == -1) {
		d_printf("Could not create file %s: %s\n", fpath1,
			 smbcli_errstr(cli_nt->tree));
		goto fail;
	}
	smbcli_close(cli_nt->tree, fnum);

	/*
	 * Do a whole bunch of error code checks on chkpath
	 */

	status = smbcli_chkpath(cli_nt->tree, fpath);
	CHECK_STATUS(status, NT_STATUS_NOT_A_DIRECTORY);
	status = smbcli_chkpath(cli_dos->tree, fpath);
	CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS, ERRbadpath));

	status = smbcli_chkpath(cli_nt->tree, "..");
	CHECK_STATUS(status, NT_STATUS_OBJECT_PATH_SYNTAX_BAD);
	status = smbcli_chkpath(cli_dos->tree, "..");
	CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS, ERRinvalidpath));

	status = smbcli_chkpath(cli_nt->tree, ".");
	CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_INVALID);
	status = smbcli_chkpath(cli_dos->tree, ".");
	CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS, ERRbadpath));

	status = smbcli_chkpath(cli_nt->tree, "\t");
	CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_INVALID);
	status = smbcli_chkpath(cli_dos->tree, "\t");
	CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS, ERRbadpath));

	status = smbcli_chkpath(cli_nt->tree, "\t\\bla");
	CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_INVALID);
	status = smbcli_chkpath(cli_dos->tree, "\t\\bla");
	CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS, ERRbadpath));

	status = smbcli_chkpath(cli_nt->tree, "<");
	CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_INVALID);
	status = smbcli_chkpath(cli_dos->tree, "<");
	CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS, ERRbadpath));

	status = smbcli_chkpath(cli_nt->tree, "<\\bla");
	CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_INVALID);
	status = smbcli_chkpath(cli_dos->tree, "<\\bla");
	CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS, ERRbadpath));

	/*
	 * .... And the same gang against getatr. Note that the DOS error codes
	 * differ....
	 */

	status = smbcli_getatr(cli_nt->tree, fpath, NULL, NULL, NULL);
	CHECK_STATUS(status, NT_STATUS_OK);
	status = smbcli_getatr(cli_dos->tree, fpath, NULL, NULL, NULL);
	CHECK_STATUS(status, NT_STATUS_OK);

	status = smbcli_getatr(cli_nt->tree, "..", NULL, NULL, NULL);
	CHECK_STATUS(status, NT_STATUS_OBJECT_PATH_SYNTAX_BAD);
	status = smbcli_getatr(cli_dos->tree, "..", NULL, NULL, NULL);
	CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS, ERRinvalidpath));

	status = smbcli_getatr(cli_nt->tree, ".", NULL, NULL, NULL);
	CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_INVALID);
	status = smbcli_getatr(cli_dos->tree, ".", NULL, NULL, NULL);
	CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS, ERRinvalidname));

	status = smbcli_getatr(cli_nt->tree, "\t", NULL, NULL, NULL);
	CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_INVALID);
	status = smbcli_getatr(cli_dos->tree, "\t", NULL, NULL, NULL);
	CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS, ERRinvalidname));

	status = smbcli_getatr(cli_nt->tree, "\t\\bla", NULL, NULL, NULL);
	CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_INVALID);
	status = smbcli_getatr(cli_dos->tree, "\t\\bla", NULL, NULL, NULL);
	CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS, ERRinvalidname));

	status = smbcli_getatr(cli_nt->tree, "<", NULL, NULL, NULL);
	CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_INVALID);
	status = smbcli_getatr(cli_dos->tree, "<", NULL, NULL, NULL);
	CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS, ERRinvalidname));

	status = smbcli_getatr(cli_nt->tree, "<\\bla", NULL, NULL, NULL);
	CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_INVALID);
	status = smbcli_getatr(cli_dos->tree, "<\\bla", NULL, NULL, NULL);
	CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS, ERRinvalidname));

	/* Try the same set with openX. */

	status = raw_smbcli_open(cli_nt->tree, "..", O_RDONLY, DENY_NONE, NULL);
	CHECK_STATUS(status, NT_STATUS_OBJECT_PATH_SYNTAX_BAD);
	status = raw_smbcli_open(cli_dos->tree, "..", O_RDONLY, DENY_NONE, NULL);
	CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS, ERRinvalidpath));

	status = raw_smbcli_open(cli_nt->tree, ".", O_RDONLY, DENY_NONE, NULL);
	CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_INVALID);
	status = raw_smbcli_open(cli_dos->tree, ".", O_RDONLY, DENY_NONE, NULL);
	CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS, ERRinvalidname));

	status = raw_smbcli_open(cli_nt->tree, "\t", O_RDONLY, DENY_NONE, NULL);
	CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_INVALID);
	status = raw_smbcli_open(cli_dos->tree, "\t", O_RDONLY, DENY_NONE, NULL);
	CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS, ERRinvalidname));

	status = raw_smbcli_open(cli_nt->tree, "\t\\bla", O_RDONLY, DENY_NONE, NULL);
	CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_INVALID);
	status = raw_smbcli_open(cli_dos->tree, "\t\\bla", O_RDONLY, DENY_NONE, NULL);
	CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS, ERRinvalidname));

	status = raw_smbcli_open(cli_nt->tree, "<", O_RDONLY, DENY_NONE, NULL);
	CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_INVALID);
	status = raw_smbcli_open(cli_dos->tree, "<", O_RDONLY, DENY_NONE, NULL);
	CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS, ERRinvalidname));

	status = raw_smbcli_open(cli_nt->tree, "<\\bla", O_RDONLY, DENY_NONE, NULL);
	CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_INVALID);
	status = raw_smbcli_open(cli_dos->tree, "<\\bla", O_RDONLY, DENY_NONE, NULL);
	CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS, ERRinvalidname));

	/* Let's test EEXIST error code mapping. */
	status = raw_smbcli_open(cli_nt->tree, fpath, O_RDONLY | O_CREAT| O_EXCL, DENY_NONE, NULL);
	CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_COLLISION);
	status = raw_smbcli_open(cli_dos->tree, fpath, O_RDONLY | O_CREAT| O_EXCL, DENY_NONE, NULL);
	CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS,ERRfilexists));

	status = raw_smbcli_t2open(cli_nt->tree, fpath, O_RDONLY | O_CREAT| O_EXCL, DENY_NONE, NULL);
	if (!NT_STATUS_EQUAL(status, NT_STATUS_EAS_NOT_SUPPORTED)
	    || !torture_setting_bool(torture, "samba3", false)) {
		/* Against samba3, treat EAS_NOT_SUPPORTED as acceptable */
		CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_COLLISION);
	}
	status = raw_smbcli_t2open(cli_dos->tree, fpath, O_RDONLY | O_CREAT| O_EXCL, DENY_NONE, NULL);
	if (!NT_STATUS_EQUAL(status, NT_STATUS_DOS(ERRDOS,ERReasnotsupported))
	    || !torture_setting_bool(torture, "samba3", false)) {
		/* Against samba3, treat EAS_NOT_SUPPORTED as acceptable */
		CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS,ERRfilexists));
	}

	status = raw_smbcli_ntcreate(cli_nt->tree, fpath, NULL);
	CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_COLLISION);
	status = raw_smbcli_ntcreate(cli_dos->tree, fpath, NULL);
	CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS,ERRfilexists));

	/* Try the rename test. */
	{
		union smb_rename io;
		memset(&io, '\0', sizeof(io));
		io.rename.in.pattern1 = fpath1;
		io.rename.in.pattern2 = fpath;

		/* Try with SMBmv rename. */
		status = smb_raw_rename(cli_nt->tree, &io);
		CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_COLLISION);
		status = smb_raw_rename(cli_dos->tree, &io);
		CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS,ERRrename));

		/* Try with NT rename. */
		io.generic.level = RAW_RENAME_NTRENAME;
		io.ntrename.in.old_name = fpath1;
		io.ntrename.in.new_name = fpath;
		io.ntrename.in.attrib = 0;
		io.ntrename.in.cluster_size = 0;
		io.ntrename.in.flags = RENAME_FLAG_RENAME;

		status = smb_raw_rename(cli_nt->tree, &io);
		CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_COLLISION);
		status = smb_raw_rename(cli_dos->tree, &io);
		CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS,ERRrename));
	}

	goto done;

 fail:
	ret = false;

 done:
	if (cli_nt != NULL) {
		smbcli_deltree(cli_nt->tree, dirname);
		torture_close_connection(cli_nt);
	}
	if (cli_dos != NULL) {
		torture_close_connection(cli_dos);
	}
	talloc_free(mem_ctx);

	return ret;
}