Beispiel #1
0
/* 
   set what accounts have a given right - this is an internal interface
*/
static NTSTATUS privilege_set_accounts_with_right(const char *right, 
						  uint32 count, 
						  DOM_SID *sids)
{
	TDB_DATA data;
	char *p;
	int i;

	if (!tdb) {
		return NT_STATUS_INTERNAL_ERROR;
	}

	/* allocate the maximum size that we might use */
	data.dptr = malloc(count * ((MAXSUBAUTHS*11) + 30));
	if (!data.dptr) {
		return NT_STATUS_NO_MEMORY;
	}

	p = data.dptr;

	for (i=0;i<count;i++) {
		sid_to_string(p, &sids[i]);
		p += strlen(p) + 1;
	}

	data.dsize = PTR_DIFF(p, data.dptr);

	if (tdb_store_bystring(tdb, right, data, TDB_REPLACE) != 0) {
		free(data.dptr);
		return NT_STATUS_INTERNAL_ERROR;
	}

	free(data.dptr);
	return NT_STATUS_OK;
}
Beispiel #2
0
BOOL regdb_store_values( const char *key, REGVAL_CTR *values )
{
	TDB_DATA data;
	pstring keystr;
	int len, ret;
	
	DEBUG(10,("regdb_store_values: Looking for value of key [%s] \n", key));
	
	ZERO_STRUCT( data );
	
	len = regdb_pack_values( values, data.dptr, data.dsize );
	if ( len <= 0 ) {
		DEBUG(0,("regdb_store_values: unable to pack values. len <= 0\n"));
		return False;
	}
	
	data.dptr = SMB_MALLOC_ARRAY( char, len );
	data.dsize = len;
	
	len = regdb_pack_values( values, data.dptr, data.dsize );
	
	SMB_ASSERT( len == data.dsize );
	
	pstr_sprintf( keystr, "%s/%s", VALUE_PREFIX, key );
	normalize_reg_path( keystr );
	
	ret = tdb_store_bystring(tdb_reg, keystr, data, TDB_REPLACE);
	
	SAFE_FREE( data.dptr );
	
	return ret != -1 ;
}
Beispiel #3
0
static void set_job_list(char *printer, struct vlp_job *job_list, 
			 int num_jobs)
{
	fstring keystr;
	TDB_DATA data;

	slprintf(keystr, sizeof(keystr) - 1, "LPQ/%s", printer);

	data.dptr = (unsigned char *)job_list;
	data.dsize = num_jobs * sizeof(struct vlp_job);
	tdb_store_bystring(tdb, keystr, data, TDB_REPLACE);
}
Beispiel #4
0
static
NTSTATUS schannel_store_session_key_tdb(struct tdb_wrap *tdb_sc,
					TALLOC_CTX *mem_ctx,
					struct netlogon_creds_CredentialState *creds)
{
	enum ndr_err_code ndr_err;
	DATA_BLOB blob;
	TDB_DATA value;
	int ret;
	char *keystr;
	char *name_upper;

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

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

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

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

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

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

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

	talloc_free(keystr);

	return NT_STATUS_OK;
}
Beispiel #5
0
bool login_cache_write(const struct samu *sampass,
		       const struct login_cache *entry)
{
	char *keystr;
	TDB_DATA databuf;
	bool ret;
	uint32_t entry_timestamp;
	uint32_t bad_password_time = entry->bad_password_time;

	if (!login_cache_init())
		return False;

	if (pdb_get_nt_username(sampass) == NULL) {
		return False;
	}

	keystr = SMB_STRDUP(pdb_get_nt_username(sampass));
	if (!keystr || !keystr[0]) {
		SAFE_FREE(keystr);
		return False;
	}

	entry_timestamp = (uint32_t)time(NULL);

	databuf.dsize = 
		tdb_pack(NULL, 0, SAM_CACHE_FORMAT,
			 entry_timestamp,
			 entry->acct_ctrl,
			 entry->bad_password_count,
			 bad_password_time);
	databuf.dptr = SMB_MALLOC_ARRAY(uint8_t, databuf.dsize);
	if (!databuf.dptr) {
		SAFE_FREE(keystr);
		return False;
	}

	if (tdb_pack(databuf.dptr, databuf.dsize, SAM_CACHE_FORMAT,
			 entry_timestamp,
			 entry->acct_ctrl,
			 entry->bad_password_count,
			 bad_password_time)
	    != databuf.dsize) {
		SAFE_FREE(keystr);
		SAFE_FREE(databuf.dptr);
		return False;
	}

	ret = tdb_store_bystring(cache, keystr, databuf, 0);
	SAFE_FREE(keystr);
	SAFE_FREE(databuf.dptr);
	return ret == 0;
}
Beispiel #6
0
static void cache_mangled_name( const char mangled_name[13],
				const char *raw_name )
{
	TDB_DATA data_val;
	char mangled_name_key[13];
	char *s1 = NULL;
	char *s2 = NULL;

	/* If the cache isn't initialized, give up. */
	if( !tdb_mangled_cache )
		return;

	/* Init the string lengths. */
	strlcpy(mangled_name_key, mangled_name, sizeof(mangled_name_key));

	/* See if the extensions are unmangled.  If so, store the entry
	 * without the extension, thus creating a "group" reverse map.
	 */
	s1 = strrchr( mangled_name_key, '.' );
	if( s1 && (s2 = strrchr( raw_name, '.' )) ) {
		size_t i = 1;
		while( s1[i] && (tolower_m( s1[i] ) == s2[i]) )
			i++;
		if( !s1[i] && !s2[i] ) {
			/* Truncate at the '.' */
			*s1 = '\0';
			/*
			 * DANGER WILL ROBINSON - this
			 * is changing a const string via
			 * an aliased pointer ! Remember to
			 * put it back once we've used it.
			 * JRA
			 */
			*s2 = '\0';
		}
	}

	/* Allocate a new cache entry.  If the allocation fails, just return. */
	data_val = string_term_tdb_data(raw_name);
	if (tdb_store_bystring(tdb_mangled_cache, mangled_name_key, data_val, TDB_REPLACE) != 0) {
		DEBUG(0,("cache_mangled_name: Error storing entry %s -> %s\n", mangled_name_key, raw_name));
	} else {
		DEBUG(5,("cache_mangled_name: Stored entry %s -> %s\n", mangled_name_key, raw_name));
	}
	/* Restore the change we made to the const string. */
	if (s2) {
		*s2 = '.';
	}
}
Beispiel #7
0
/* load a msg file into the tdb */
static bool load_msg(const char *msg_file)
{
	char **lines;
	int num_lines, i;
	char *msgid, *msgstr;
	TDB_DATA data;

	lines = file_lines_load(msg_file, &num_lines, 0, NULL);

	if (!lines) {
		return False;
	}

	if (tdb_lockall(tdb) != 0) {
		TALLOC_FREE(lines);
		return False;
	}

	/* wipe the db */
	tdb_wipe_all(tdb);

	msgid = NULL;
	
	for (i=0;i<num_lines;i++) {
		if (strncmp(lines[i], "msgid \"", 7) == 0) {
			msgid = lines[i] + 7;
		}
		if (msgid && strncmp(lines[i], "msgstr \"", 8) == 0) {
			msgstr = lines[i] + 8;
			trim_char(msgid, '\0', '\"');
			trim_char(msgstr, '\0', '\"');
			if (*msgstr == 0) {
				msgstr = msgid;
			}
			all_string_sub(msgid, "\\n", "\n", 0);
			all_string_sub(msgstr, "\\n", "\n", 0);
			data = string_term_tdb_data(msgstr);
			tdb_store_bystring(tdb, msgid, data, 0);
			msgid = NULL;
		}
	}

	TALLOC_FREE(lines);
	tdb_unlockall(tdb);

	return True;
}
Beispiel #8
0
/*
  save the notify array
*/
static NTSTATUS notify_save(struct notify_context *notify)
{
	TDB_DATA dbuf;
	DATA_BLOB blob;
	enum ndr_err_code ndr_err;
	int ret;
	TALLOC_CTX *tmp_ctx;

	/* if possible, remove some depth arrays */
	while (notify->array->num_depths > 0 &&
	       notify->array->depth[notify->array->num_depths-1].num_entries == 0) {
		notify->array->num_depths--;
	}

	/* we might just be able to delete the record */
	if (notify->array->num_depths == 0) {
		ret = tdb_delete_bystring(notify->w->tdb, NOTIFY_KEY);
		if (ret != 0) {
			return NT_STATUS_INTERNAL_DB_CORRUPTION;
		}
		return NT_STATUS_OK;
	}

	tmp_ctx = talloc_new(notify);
	NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);

	ndr_err = ndr_push_struct_blob(&blob, tmp_ctx, notify->array,
				       (ndr_push_flags_fn_t)ndr_push_notify_array);
	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
		talloc_free(tmp_ctx);
		return ndr_map_error2ntstatus(ndr_err);
	}

	dbuf.dptr = blob.data;
	dbuf.dsize = blob.length;
		
	ret = tdb_store_bystring(notify->w->tdb, NOTIFY_KEY, dbuf, TDB_REPLACE);
	talloc_free(tmp_ctx);
	if (ret != 0) {
		return NT_STATUS_INTERNAL_DB_CORRUPTION;
	}

	return NT_STATUS_OK;
}
Beispiel #9
0
static void cache_mangled_name( const char mangled_name[13],
				const char *raw_name )
{
	TDB_DATA data_val;
	char mangled_name_key[13];
	char *s1;
	char *s2;

	/* If the cache isn't initialized, give up. */
	if( !tdb_mangled_cache )
		return;

	/* Init the string lengths. */
	safe_strcpy(mangled_name_key, mangled_name, sizeof(mangled_name_key)-1);

	/* See if the extensions are unmangled.  If so, store the entry
	 * without the extension, thus creating a "group" reverse map.
	 */
	s1 = strrchr( mangled_name_key, '.' );
	if( s1 && (s2 = strrchr( raw_name, '.' )) ) {
		size_t i = 1;
		while( s1[i] && (tolower_ascii( s1[i] ) == s2[i]) )
			i++;
		if( !s1[i] && !s2[i] ) {
			/* Truncate at the '.' */
			*s1 = '\0';
			*s2 = '\0';
		}
	}

	/* Allocate a new cache entry.  If the allocation fails, just return. */
	data_val = string_term_tdb_data(raw_name);
	if (tdb_store_bystring(tdb_mangled_cache, mangled_name_key, data_val, TDB_REPLACE) != 0) {
		DEBUG(0,("cache_mangled_name: Error storing entry %s -> %s\n", mangled_name_key, raw_name));
	} else {
		DEBUG(5,("cache_mangled_name: Stored entry %s -> %s\n", mangled_name_key, raw_name));
	}
}
Beispiel #10
0
static bool do_winbind_offline(struct tevent_context *ev_ctx,
			       struct messaging_context *msg_ctx,
			       const struct server_id pid,
			       const int argc, const char **argv)
{
	TDB_CONTEXT *tdb;
	bool ret = False;
	int retry = 0;

	if (argc != 1) {
		fprintf(stderr, "Usage: smbcontrol winbindd offline\n");
		return False;
	}

	/* Create an entry in the winbindd_cache tdb to tell a later
	   starting winbindd that we're offline. We may actually create
	   it here... */

	tdb = tdb_open_log(state_path("winbindd_cache.tdb"),
				WINBINDD_CACHE_TDB_DEFAULT_HASH_SIZE,
				TDB_DEFAULT|TDB_INCOMPATIBLE_HASH /* TDB_CLEAR_IF_FIRST */,
				O_RDWR|O_CREAT, 0600);

	if (!tdb) {
		fprintf(stderr, "Cannot open the tdb %s for writing.\n",
			state_path("winbindd_cache.tdb"));
		return False;
	}

	/* There's a potential race condition that if a child
	   winbindd detects a domain is online at the same time
	   we're trying to tell it to go offline that it might 
	   delete the record we add between us adding it and
	   sending the message. Minimize this by retrying up to
	   5 times. */

	for (retry = 0; retry < 5; retry++) {
		TDB_DATA d;
		uint8 buf[4];

		ZERO_STRUCT(d);

		SIVAL(buf, 0, time(NULL));
		d.dptr = buf;
		d.dsize = 4;

		tdb_store_bystring(tdb, "WINBINDD_OFFLINE", d, TDB_INSERT);

		ret = send_message(msg_ctx, pid, MSG_WINBIND_OFFLINE,
				   NULL, 0);

		/* Check that the entry "WINBINDD_OFFLINE" still exists. */
		d = tdb_fetch_bystring( tdb, "WINBINDD_OFFLINE" );

		if (!d.dptr || d.dsize != 4) {
			SAFE_FREE(d.dptr);
			DEBUG(10,("do_winbind_offline: offline state not set - retrying.\n"));
		} else {
			SAFE_FREE(d.dptr);
			break;
		}
	}

	tdb_close(tdb);
	return ret;
}
Beispiel #11
0
static bool test_one(struct cli_state *cli, const char *name)
{
	uint16_t fnum;
	fstring shortname;
	fstring name2;
	NTSTATUS status;
	TDB_DATA data;

	total++;

	status = cli_openx(cli, name, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
	if (!NT_STATUS_IS_OK(status)) {
		printf("open of %s failed (%s)\n", name, nt_errstr(status));
		return False;
	}

	status = cli_close(cli, fnum);
	if (!NT_STATUS_IS_OK(status)) {
		printf("close of %s failed (%s)\n", name, nt_errstr(status));
		return False;
	}

	/* get the short name */
	status = cli_qpathinfo_alt_name(cli, name, shortname);
	if (!NT_STATUS_IS_OK(status)) {
		printf("query altname of %s failed (%s)\n", name, nt_errstr(status));
		return False;
	}

	fstr_sprintf(name2, "\\mangle_test\\%s", shortname);
	status = cli_unlink(cli, name2, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
	if (!NT_STATUS_IS_OK(status)) {
		printf("unlink of %s  (%s) failed (%s)\n", 
		       name2, name, nt_errstr(status));
		return False;
	}

	/* recreate by short name */
	status = cli_openx(cli, name2, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
	if (!NT_STATUS_IS_OK(status)) {
		printf("open2 of %s failed (%s)\n", name2, nt_errstr(status));
		return False;
	}

	status = cli_close(cli, fnum);
	if (!NT_STATUS_IS_OK(status)) {
		printf("close of %s failed (%s)\n", name, nt_errstr(status));
		return False;
	}

	/* and unlink by long name */
	status = cli_unlink(cli, name, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
	if (!NT_STATUS_IS_OK(status)) {
		printf("unlink2 of %s  (%s) failed (%s)\n", 
		       name, name2, nt_errstr(status));
		failures++;
		cli_unlink(cli, name2, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
		return True;
	}

	/* see if the short name is already in the tdb */
	data = tdb_fetch_bystring(tdb, shortname);
	if (data.dptr) {
		/* maybe its a duplicate long name? */
		if (!strequal(name, (const char *)data.dptr)) {
			/* we have a collision */
			collisions++;
			printf("Collision between %s and %s   ->  %s "
				" (coll/tot: %u/%u)\n", 
				name, data.dptr, shortname, collisions, total);
		}
		free(data.dptr);
	} else {
		TDB_DATA namedata;
		/* store it for later */
		namedata.dptr = discard_const_p(uint8_t, name);
		namedata.dsize = strlen(name)+1;
		tdb_store_bystring(tdb, shortname, namedata, TDB_REPLACE);
	}

	return True;
}
Beispiel #12
0
bool netsamlogon_cache_store(const char *username, struct netr_SamInfo3 *info3)
{
    uint8_t dummy = 0;
    TDB_DATA data = { .dptr = &dummy, .dsize = sizeof(dummy) };
    char keystr[DOM_SID_STR_BUFLEN];
    bool result = false;
    struct dom_sid	user_sid;
    TALLOC_CTX *tmp_ctx = talloc_stackframe();
    DATA_BLOB blob;
    enum ndr_err_code ndr_err;
    struct netsamlogoncache_entry r;
    int ret;

    if (!info3) {
        return false;
    }

    if (!netsamlogon_cache_init()) {
        DEBUG(0,("netsamlogon_cache_store: cannot open %s for write!\n",
                 NETSAMLOGON_TDB));
        return false;
    }

    /*
     * First write a record with just the domain sid for
     * netsamlogon_cache_domain_known. Use TDB_INSERT to avoid
     * overwriting potentially other data. We're just interested
     * in the existence of that record.
     */
    dom_sid_string_buf(info3->base.domain_sid, keystr, sizeof(keystr));

    ret = tdb_store_bystring(netsamlogon_tdb, keystr, data, TDB_INSERT);

    if ((ret == -1) && (tdb_error(netsamlogon_tdb) != TDB_ERR_EXISTS)) {
        DBG_WARNING("Could not store domain marker for %s: %s\n",
                    keystr, tdb_errorstr(netsamlogon_tdb));
        TALLOC_FREE(tmp_ctx);
        return false;
    }

    sid_compose(&user_sid, info3->base.domain_sid, info3->base.rid);

    /* Prepare key as DOMAIN-SID/USER-RID string */
    dom_sid_string_buf(&user_sid, keystr, sizeof(keystr));

    DEBUG(10,("netsamlogon_cache_store: SID [%s]\n", keystr));

    /* Prepare data */

    if (info3->base.full_name.string == NULL) {
        struct netr_SamInfo3 *cached_info3;
        const char *full_name = NULL;

        cached_info3 = netsamlogon_cache_get(tmp_ctx, &user_sid);
        if (cached_info3 != NULL) {
            full_name = cached_info3->base.full_name.string;
        }

        if (full_name != NULL) {
            info3->base.full_name.string = talloc_strdup(info3, full_name);
        }
    }

    /* only Samba fills in the username, not sure why NT doesn't */
    /* so we fill it in since winbindd_getpwnam() makes use of it */

    if (!info3->base.account_name.string) {
        info3->base.account_name.string = talloc_strdup(info3, username);
    }

    r.timestamp = time(NULL);
    r.info3 = *info3;

    if (DEBUGLEVEL >= 10) {
        NDR_PRINT_DEBUG(netsamlogoncache_entry, &r);
    }

    ndr_err = ndr_push_struct_blob(&blob, tmp_ctx, &r,
                                   (ndr_push_flags_fn_t)ndr_push_netsamlogoncache_entry);
    if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
        DEBUG(0,("netsamlogon_cache_store: failed to push entry to cache\n"));
        TALLOC_FREE(tmp_ctx);
        return false;
    }

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

    if (tdb_store_bystring(netsamlogon_tdb, keystr, data, TDB_REPLACE) == 0) {
        result = true;
    }

    TALLOC_FREE(tmp_ctx);

    return result;
}

/***********************************************************************
 Retrieves a netr_SamInfo3 structure from a tdb.  Caller must
 free the user_info struct (talloced memory)
***********************************************************************/

struct netr_SamInfo3 *netsamlogon_cache_get(TALLOC_CTX *mem_ctx, const struct dom_sid *user_sid)
{
    struct netr_SamInfo3 *info3 = NULL;
    TDB_DATA data;
    char keystr[DOM_SID_STR_BUFLEN];
    enum ndr_err_code ndr_err;
    DATA_BLOB blob;
    struct netsamlogoncache_entry r;

    if (!netsamlogon_cache_init()) {
        DEBUG(0,("netsamlogon_cache_get: cannot open %s for write!\n",
                 NETSAMLOGON_TDB));
        return NULL;
    }

    /* Prepare key as DOMAIN-SID/USER-RID string */
    dom_sid_string_buf(user_sid, keystr, sizeof(keystr));
    DEBUG(10,("netsamlogon_cache_get: SID [%s]\n", keystr));
    data = tdb_fetch_bystring( netsamlogon_tdb, keystr );

    if (!data.dptr) {
        return NULL;
    }

    info3 = talloc_zero(mem_ctx, struct netr_SamInfo3);
    if (!info3) {
        goto done;
    }

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

    ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &r,
                                   (ndr_pull_flags_fn_t)ndr_pull_netsamlogoncache_entry);

    if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
        DEBUG(0,("netsamlogon_cache_get: failed to pull entry from cache\n"));
        tdb_delete_bystring(netsamlogon_tdb, keystr);
        TALLOC_FREE(info3);
        goto done;
    }

    if (DEBUGLEVEL >= 10) {
        NDR_PRINT_DEBUG(netsamlogoncache_entry, &r);
    }

    info3 = (struct netr_SamInfo3 *)talloc_memdup(mem_ctx, &r.info3,
            sizeof(r.info3));

done:
    SAFE_FREE(data.dptr);

    return info3;
}

bool netsamlogon_cache_have(const struct dom_sid *sid)
{
    char keystr[DOM_SID_STR_BUFLEN];
    bool ok;

    if (!netsamlogon_cache_init()) {
        DBG_WARNING("Cannot open %s\n", NETSAMLOGON_TDB);
        return false;
    }

    dom_sid_string_buf(sid, keystr, sizeof(keystr));

    ok = tdb_exists(netsamlogon_tdb, string_term_tdb_data(keystr));
    return ok;
}
Beispiel #13
0
static int print_command(int argc, char **argv)
{
	char *printer;
	fstring keystr;
	struct passwd *pw;
	TDB_DATA value, queue;
	struct vlp_job job;

	if (argc < 3) {
		printf("Usage: print <printername> <jobname>\n");
		return 1;
	}

	printer = argv[1];

	ZERO_STRUCT(job);

	/* Create a job record */

	slprintf(job.jobname, sizeof(job.jobname) - 1, "%s", argv[2]);

	if (!(pw = getpwuid(getuid()))) {
		return 1;
	}

	slprintf(job.owner, sizeof(job.owner) - 1, "%s", pw->pw_name);

	job.jobid = next_jobnum(printer);
	job.size = 666;
	job.submit_time = time(NULL);

	/* Store job entry in queue */

	slprintf(keystr, sizeof(keystr) - 1, "LPQ/%s", printer);

	value = tdb_fetch_bystring(tdb, keystr);

	if (value.dptr) {

		/* Add job to end of queue */

		queue.dptr = (unsigned char *)malloc(value.dsize + sizeof(struct vlp_job));
		if (!queue.dptr) return 1;

		memcpy(queue.dptr, value.dptr, value.dsize);
		memcpy(queue.dptr + value.dsize, &job, sizeof(struct vlp_job));

		queue.dsize = value.dsize + sizeof(struct vlp_job);

		tdb_store_bystring(tdb, keystr, queue, TDB_REPLACE);

		free(queue.dptr);

	} else {

		/* Create new queue */
		queue.dptr = (unsigned char *)&job;
		queue.dsize = sizeof(struct vlp_job);

		tdb_store_bystring(tdb, keystr, queue, TDB_REPLACE);
	}

	return 0;
}
Beispiel #14
0
static bool do_winbind_offline(struct tevent_context *ev_ctx,
			       struct messaging_context *msg_ctx,
			       const struct server_id pid,
			       const int argc, const char **argv)
{
	TDB_CONTEXT *tdb;
	bool ret = False;
	int retry = 0;
	char *db_path;

	if (argc != 1) {
		fprintf(stderr, "Usage: smbcontrol winbindd offline\n");
		return False;
	}

	db_path = state_path("winbindd_cache.tdb");
	if (db_path == NULL) {
		return false;
	}

	/* Create an entry in the winbindd_cache tdb to tell a later
	   starting winbindd that we're offline. We may actually create
	   it here... */

	tdb = tdb_open_log(db_path,
				WINBINDD_CACHE_TDB_DEFAULT_HASH_SIZE,
				TDB_DEFAULT|TDB_INCOMPATIBLE_HASH /* TDB_CLEAR_IF_FIRST */,
				O_RDWR|O_CREAT, 0600);

	if (!tdb) {
		fprintf(stderr, "Cannot open the tdb %s for writing.\n",
			db_path);
		TALLOC_FREE(db_path);
		return False;
	}
	TALLOC_FREE(db_path);

	/* There's a potential race condition that if a child
	   winbindd detects a domain is online at the same time
	   we're trying to tell it to go offline that it might 
	   delete the record we add between us adding it and
	   sending the message. Minimize this by retrying up to
	   5 times. */

	for (retry = 0; retry < 5; retry++) {
		uint8_t buf[4];
		TDB_DATA d = { .dptr = buf, .dsize = sizeof(buf) };

		SIVAL(buf, 0, time(NULL));

		tdb_store_bystring(tdb, "WINBINDD_OFFLINE", d, TDB_INSERT);

		ret = send_message(msg_ctx, pid, MSG_WINBIND_OFFLINE,
				   NULL, 0);

		/* Check that the entry "WINBINDD_OFFLINE" still exists. */
		d = tdb_fetch_bystring( tdb, "WINBINDD_OFFLINE" );

		if (!d.dptr || d.dsize != 4) {
			SAFE_FREE(d.dptr);
			DEBUG(10,("do_winbind_offline: offline state not set - retrying.\n"));
		} else {
			SAFE_FREE(d.dptr);
			break;
		}
	}

	tdb_close(tdb);
	return ret;
}

static bool do_winbind_onlinestatus(struct tevent_context *ev_ctx,
				    struct messaging_context *msg_ctx,
				    const struct server_id pid,
				    const int argc, const char **argv)
{
	struct server_id myid;

	myid = messaging_server_id(msg_ctx);

	if (argc != 1) {
		fprintf(stderr, "Usage: smbcontrol winbindd onlinestatus\n");
		return False;
	}

	messaging_register(msg_ctx, NULL, MSG_WINBIND_ONLINESTATUS,
			   print_pid_string_cb);

	if (!send_message(msg_ctx, pid, MSG_WINBIND_ONLINESTATUS, &myid,
			  sizeof(myid)))
		return False;

	wait_replies(ev_ctx, msg_ctx, procid_to_pid(&pid) == 0);

	/* No replies were received within the timeout period */

	if (num_replies == 0)
		printf("No replies received\n");

	messaging_deregister(msg_ctx, MSG_WINBIND_ONLINESTATUS, NULL);

	return num_replies;
}

static bool do_dump_event_list(struct tevent_context *ev_ctx,
			       struct messaging_context *msg_ctx,
			       const struct server_id pid,
			       const int argc, const char **argv)
{
	if (argc != 1) {
		fprintf(stderr, "Usage: smbcontrol <dest> dump-event-list\n");
		return False;
	}

	return send_message(msg_ctx, pid, MSG_DUMP_EVENT_LIST, NULL, 0);
}

static bool do_winbind_dump_domain_list(struct tevent_context *ev_ctx,
					struct messaging_context *msg_ctx,
					const struct server_id pid,
					const int argc, const char **argv)
{
	const char *domain = NULL;
	int domain_len = 0;
	struct server_id myid;
	uint8_t *buf = NULL;
	int buf_len = 0;

	myid = messaging_server_id(msg_ctx);

	if (argc < 1 || argc > 2) {
		fprintf(stderr, "Usage: smbcontrol <dest> dump-domain-list "
			"<domain>\n");
		return false;
	}

	if (argc == 2) {
		domain = argv[1];
		domain_len = strlen(argv[1]) + 1;
	}

	messaging_register(msg_ctx, NULL, MSG_WINBIND_DUMP_DOMAIN_LIST,
			   print_pid_string_cb);

	buf_len = sizeof(myid)+domain_len;
	buf = SMB_MALLOC_ARRAY(uint8_t, buf_len);
	if (!buf) {
		return false;
	}

	memcpy(buf, &myid, sizeof(myid));
	memcpy(&buf[sizeof(myid)], domain, domain_len);

	if (!send_message(msg_ctx, pid, MSG_WINBIND_DUMP_DOMAIN_LIST,
			  buf, buf_len))
	{
		SAFE_FREE(buf);
		return false;
	}

	wait_replies(ev_ctx, msg_ctx, procid_to_pid(&pid) == 0);

	/* No replies were received within the timeout period */

	SAFE_FREE(buf);
	if (num_replies == 0) {
		printf("No replies received\n");
	}

	messaging_deregister(msg_ctx, MSG_WINBIND_DUMP_DOMAIN_LIST, NULL);

	return num_replies;
}

static void winbind_validate_cache_cb(struct messaging_context *msg,
				      void *private_data,
				      uint32_t msg_type,
				      struct server_id pid,
				      DATA_BLOB *data)
{
	struct server_id_buf src_string;
	printf("Winbindd cache is %svalid. (answer from pid %s)\n",
	       (*(data->data) == 0 ? "" : "NOT "),
	       server_id_str_buf(pid, &src_string));
	num_replies++;
}

static bool do_winbind_validate_cache(struct tevent_context *ev_ctx,
				      struct messaging_context *msg_ctx,
				      const struct server_id pid,
				      const int argc, const char **argv)
{
	struct server_id myid;

	myid = messaging_server_id(msg_ctx);

	if (argc != 1) {
		fprintf(stderr, "Usage: smbcontrol winbindd validate-cache\n");
		return False;
	}

	messaging_register(msg_ctx, NULL, MSG_WINBIND_VALIDATE_CACHE,
			   winbind_validate_cache_cb);

	if (!send_message(msg_ctx, pid, MSG_WINBIND_VALIDATE_CACHE, &myid,
			  sizeof(myid))) {
		return False;
	}

	wait_replies(ev_ctx, msg_ctx, procid_to_pid(&pid) == 0);

	if (num_replies == 0) {
		printf("No replies received\n");
	}

	messaging_deregister(msg_ctx, MSG_WINBIND_VALIDATE_CACHE, NULL);

	return num_replies;
}

static bool do_reload_config(struct tevent_context *ev_ctx,
			     struct messaging_context *msg_ctx,
			     const struct server_id pid,
			     const int argc, const char **argv)
{
	if (argc != 1) {
		fprintf(stderr, "Usage: smbcontrol <dest> reload-config\n");
		return False;
	}

	return send_message(msg_ctx, pid, MSG_SMB_CONF_UPDATED, NULL, 0);
}

static bool do_reload_printers(struct tevent_context *ev_ctx,
			       struct messaging_context *msg_ctx,
			       const struct server_id pid,
			       const int argc, const char **argv)
{
	if (argc != 1) {
		fprintf(stderr, "Usage: smbcontrol <dest> reload-printers\n");
		return False;
	}

	return send_message(msg_ctx, pid, MSG_PRINTER_PCAP, NULL, 0);
}

static void my_make_nmb_name( struct nmb_name *n, const char *name, int type)
{
	fstring unix_name;
	memset( (char *)n, '\0', sizeof(struct nmb_name) );
	fstrcpy(unix_name, name);
	(void)strupper_m(unix_name);
	push_ascii(n->name, unix_name, sizeof(n->name), STR_TERMINATE);
	n->name_type = (unsigned int)type & 0xFF;
	push_ascii(n->scope,  lp_netbios_scope(), 64, STR_TERMINATE);
}
Beispiel #15
0
static BOOL test_one(struct smbcli_state *cli, const char *name)
{
	int fnum;
	const char *shortname;
	fstring name2;
	NTSTATUS status;
	TDB_DATA data;

	total++;

	fnum = smbcli_open(cli->tree, name, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
	if (fnum == -1) {
		printf("open of %s failed (%s)\n", name, smbcli_errstr(cli->tree));
		return False;
	}

	if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum))) {
		printf("close of %s failed (%s)\n", name, smbcli_errstr(cli->tree));
		return False;
	}

	/* get the short name */
	status = smbcli_qpathinfo_alt_name(cli->tree, name, &shortname);
	if (!NT_STATUS_IS_OK(status)) {
		printf("query altname of %s failed (%s)\n", name, smbcli_errstr(cli->tree));
		return False;
	}

	snprintf(name2, sizeof(name2), "\\mangle_test\\%s", shortname);
	if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, name2))) {
		printf("unlink of %s  (%s) failed (%s)\n", 
		       name2, name, smbcli_errstr(cli->tree));
		return False;
	}

	/* recreate by short name */
	fnum = smbcli_open(cli->tree, name2, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
	if (fnum == -1) {
		printf("open2 of %s failed (%s)\n", name2, smbcli_errstr(cli->tree));
		return False;
	}
	if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum))) {
		printf("close of %s failed (%s)\n", name, smbcli_errstr(cli->tree));
		return False;
	}

	/* and unlink by long name */
	if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, name))) {
		printf("unlink2 of %s  (%s) failed (%s)\n", 
		       name, name2, smbcli_errstr(cli->tree));
		failures++;
		smbcli_unlink(cli->tree, name2);
		return True;
	}

	/* see if the short name is already in the tdb */
	data = tdb_fetch_bystring(tdb, shortname);
	if (data.dptr) {
		/* maybe its a duplicate long name? */
		if (strcasecmp(name, (const char *)data.dptr) != 0) {
			/* we have a collision */
			collisions++;
			printf("Collision between %s and %s   ->  %s "
				" (coll/tot: %u/%u)\n", 
				name, data.dptr, shortname, collisions, total);
		}
		free(data.dptr);
	} else {
		TDB_DATA namedata;
		/* store it for later */
		namedata.dptr = discard_const_p(uint8_t, name);
		namedata.dsize = strlen(name)+1;
		tdb_store_bystring(tdb, shortname, namedata, TDB_REPLACE);
	}

	return True;
}