示例#1
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);

	/* 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;
}
示例#2
0
static BOOL check_cache( char *s, size_t maxlen, int snum )
{
	TDB_DATA data_val;
	char *ext_start = NULL;
	char *saved_ext = NULL;

	magic_char = lp_magicchar(snum);

	/* If the cache isn't initialized, give up. */
	if( !tdb_mangled_cache )
		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) {
		ext_start = strrchr( s, '.' );
		if( ext_start ) {
			if((saved_ext = SMB_STRDUP(ext_start)) == NULL)
				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) {
		if(saved_ext) {
			/* Replace the saved_ext as it was truncated. */
			(void)safe_strcat( s, saved_ext, maxlen );
			SAFE_FREE(saved_ext);
		}
		return( False );
	}

	/* If we *did* find it, we need to copy it into the string buffer. */
	(void)safe_strcpy( s, data_val.dptr, maxlen );
	if( saved_ext ) {
		/* Replace the saved_ext as it was truncated. */
		(void)safe_strcat( s, saved_ext, maxlen );
		SAFE_FREE(saved_ext);
	}
	SAFE_FREE(data_val.dptr);
	return( True );
}
示例#3
0
/* if we can't read the cache, oh well, no need to return anything */
bool login_cache_read(struct samu *sampass, struct login_cache *entry)
{
	char *keystr;
	TDB_DATA databuf;
	uint32_t entry_timestamp = 0, bad_password_time = 0;
	uint16_t acct_ctrl;

	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;
	}

	DEBUG(7, ("Looking up login cache for user %s\n",
		  keystr));
	databuf = tdb_fetch_bystring(cache, keystr);
	SAFE_FREE(keystr);

	ZERO_STRUCTP(entry);

	if (tdb_unpack (databuf.dptr, databuf.dsize, SAM_CACHE_FORMAT,
			&entry_timestamp,
			&acct_ctrl,
			&entry->bad_password_count,
			&bad_password_time) == -1) {
		DEBUG(7, ("No cache entry found\n"));
		SAFE_FREE(databuf.dptr);
		return false;
	}

	/*
	 * Deal with 32-bit acct_ctrl. In the tdb we only store 16-bit
	 * ("w" in SAM_CACHE_FORMAT). Fixes bug 7253.
	 */
	entry->acct_ctrl = acct_ctrl;

	/* Deal with possible 64-bit time_t. */
	entry->entry_timestamp = (time_t)entry_timestamp;
	entry->bad_password_time = (time_t)bad_password_time;

	SAFE_FREE(databuf.dptr);

	DEBUG(5, ("Found login cache entry: timestamp %12u, flags 0x%x, count %d, time %12u\n",
		  (unsigned int)entry->entry_timestamp, entry->acct_ctrl, 
		  entry->bad_password_count, (unsigned int)entry->bad_password_time));
	return true;
}
示例#4
0
TDB_DATA get_printer_notify_pid_list(TDB_CONTEXT *tdb, const char *printer_name, BOOL cleanlist)
{
	TDB_DATA data;
	size_t i;

	ZERO_STRUCT(data);

	data = tdb_fetch_bystring( tdb, NOTIFY_PID_LIST_KEY );

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

	if (data.dsize % 8) {
		DEBUG(0,("get_printer_notify_pid_list: Size of record for printer %s not a multiple of 8 !\n", printer_name ));
		tdb_delete_bystring(tdb, NOTIFY_PID_LIST_KEY );
		SAFE_FREE(data.dptr);
		ZERO_STRUCT(data);
		return data;
	}

	if (!cleanlist)
		return data;

	/*
	 * Weed out all dead entries.
	 */

	for( i = 0; i < data.dsize; i += 8) {
		pid_t pid = (pid_t)IVAL(data.dptr, i);

		if (pid == sys_getpid())
			continue;

		/* Entry is dead if process doesn't exist or refcount is zero. */

		while ((i < data.dsize) && ((IVAL(data.dptr, i + 4) == 0) || !process_exists(pid))) {

			/* Refcount == zero is a logic error and should never happen. */
			if (IVAL(data.dptr, i + 4) == 0) {
				DEBUG(0,("get_printer_notify_pid_list: Refcount == 0 for pid = %u printer %s !\n",
							(unsigned int)pid, printer_name ));
			}

			if (data.dsize - i > 8)
				memmove( &data.dptr[i], &data.dptr[i+8], data.dsize - i - 8);
			data.dsize -= 8;
		}
	}

	return data;
}
示例#5
0
文件: vlp.c 项目: 0x24bin/winexe-1
static void get_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 = tdb_fetch_bystring(tdb, keystr);

	*job_list = (struct vlp_job *)data.dptr;
	*num_jobs = data.dsize / sizeof(struct vlp_job);
}
示例#6
0
/* translate a msgid to a message string in the current language 
   returns a string that must be freed by calling lang_msg_free()
*/
const char *lang_msg(const char *msgid)
{
	TDB_DATA data;
	const char *p;
	char *q, *msgid_quoted;
	int count;

	lang_tdb_init(NULL);

	if (!tdb) return msgid;

	/* Due to the way quotes in msgids are escaped in the msg file we
	   must replace " with \" before doing a lookup in the tdb. */

	count = 0;

	for(p = msgid; *p; p++) {
		if (*p == '\"')
			count++;
	}

	if (!(msgid_quoted = (char *)SMB_MALLOC(strlen(msgid) + count + 1)))
		return msgid;

	/* string_sub() is unsuitable here as it replaces some punctuation
	   chars with underscores. */

	for(p = msgid, q = msgid_quoted; *p; p++) {
		if (*p == '\"') {
			*q = '\\';
			q++;
		}
		*q = *p;
		q++;
	}

	*q = 0;

	data = tdb_fetch_bystring(tdb, msgid_quoted);

	free(msgid_quoted);

	/* if the message isn't found then we still need to return a pointer
	   that can be freed. Pity. */
	if (!data.dptr)
		return SMB_STRDUP(msgid);

	return (const char *)data.dptr;
}
示例#7
0
/* if we can't read the cache, oh well, no need to return anything */
LOGIN_CACHE * login_cache_read(struct samu *sampass)
{
	char *keystr;
	TDB_DATA databuf;
	LOGIN_CACHE *entry;

	if (!login_cache_init())
		return NULL;

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

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

	DEBUG(7, ("Looking up login cache for user %s\n",
		  keystr));
	databuf = tdb_fetch_bystring(cache, keystr);
	SAFE_FREE(keystr);

	if (!(entry = SMB_MALLOC_P(LOGIN_CACHE))) {
		DEBUG(1, ("Unable to allocate cache entry buffer!\n"));
		SAFE_FREE(databuf.dptr);
		return NULL;
	}

	if (tdb_unpack (databuf.dptr, databuf.dsize, SAM_CACHE_FORMAT,
			&entry->entry_timestamp, &entry->acct_ctrl, 
			&entry->bad_password_count, 
			&entry->bad_password_time) == -1) {
		DEBUG(7, ("No cache entry found\n"));
		SAFE_FREE(entry);
		SAFE_FREE(databuf.dptr);
		return NULL;
	}

	SAFE_FREE(databuf.dptr);

	DEBUG(5, ("Found login cache entry: timestamp %12u, flags 0x%x, count %d, time %12u\n",
		  (unsigned int)entry->entry_timestamp, entry->acct_ctrl, 
		  entry->bad_password_count, (unsigned int)entry->bad_password_time));
	return entry;
}
示例#8
0
/* 
   return a list of SIDs that have a particular right
*/
NTSTATUS privilege_enum_account_with_right(const char *right, 
					   uint32 *count, 
					   DOM_SID **sids)
{
	TDB_DATA data;
	char *p;
	int i;

	if (!tdb) {
		return NT_STATUS_INTERNAL_ERROR;
	}

	data = tdb_fetch_bystring(tdb, right);
	if (!data.dptr) {
		*count = 0;
		*sids = NULL;
		return NT_STATUS_OK;
	}

	/* count them */
	for (i=0, p=data.dptr; p<data.dptr+data.dsize; i++) {
		p += strlen(p) + 1;
	}
	*count = i;

	/* allocate and parse */
	*sids = malloc(sizeof(DOM_SID) * *count);
	if (! *sids) {
		return NT_STATUS_NO_MEMORY;
	}
	for (i=0, p=data.dptr; p<data.dptr+data.dsize; i++) {
		if (!string_to_sid(&(*sids)[i], p)) {
			free(data.dptr);
			return NT_STATUS_INTERNAL_DB_CORRUPTION;
		}
		p += strlen(p) + 1;
	}
	
	free(data.dptr);

	return NT_STATUS_OK;
}
示例#9
0
文件: reg_db.c 项目: AllardJ/Tomato
int regdb_fetch_keys( const char* key, REGSUBKEY_CTR *ctr )
{
	pstring path;
	uint32 num_items;
	TDB_DATA dbuf;
	char *buf;
	uint32 buflen, len;
	int i;
	fstring subkeyname;

	DEBUG(11,("regdb_fetch_keys: Enter key => [%s]\n", key ? key : "NULL"));
	
	pstrcpy( path, key );
	
	/* convert to key format */
	pstring_sub( path, "\\", "/" ); 
	strupper_m( path );
	
	dbuf = tdb_fetch_bystring( tdb_reg, path );
	
	buf = dbuf.dptr;
	buflen = dbuf.dsize;
	
	if ( !buf ) {
		DEBUG(5,("regdb_fetch_keys: tdb lookup failed to locate key [%s]\n", key));
		return -1;
	}
	
	len = tdb_unpack( buf, buflen, "d", &num_items);
	
	for (i=0; i<num_items; i++) {
		len += tdb_unpack( buf+len, buflen-len, "f", subkeyname );
		regsubkey_ctr_addkey( ctr, subkeyname );
	}

	SAFE_FREE( dbuf.dptr );
	
	DEBUG(11,("regdb_fetch_keys: Exit [%d] items\n", num_items));
	
	return num_items;
}
示例#10
0
static NTSTATUS fetch_cache_seqnum( struct winbindd_domain *domain, time_t now )
{
	TDB_DATA data;
	fstring key;
	uint32 time_diff;
	
	if (!wcache->tdb) {
		DEBUG(10,("fetch_cache_seqnum: tdb == NULL\n"));
		return NT_STATUS_UNSUCCESSFUL;
	}
		
	fstr_sprintf( key, "SEQNUM/%s", domain->name );
	
	data = tdb_fetch_bystring( wcache->tdb, key );
	if ( !data.dptr || data.dsize!=8 ) {
		DEBUG(10,("fetch_cache_seqnum: invalid data size key [%s]\n", key ));
		return NT_STATUS_UNSUCCESSFUL;
	}
	
	domain->sequence_number = IVAL(data.dptr, 0);
	domain->last_seq_check  = IVAL(data.dptr, 4);
	
	/* have we expired? */
	
	time_diff = now - domain->last_seq_check;
	if ( time_diff > lp_winbind_cache_time() ) {
		DEBUG(10,("fetch_cache_seqnum: timeout [%s][%u @ %u]\n",
			domain->name, domain->sequence_number,
			(uint32)domain->last_seq_check));
		return NT_STATUS_UNSUCCESSFUL;
	}

	DEBUG(10,("fetch_cache_seqnum: success [%s][%u @ %u]\n", 
		domain->name, domain->sequence_number, 
		(uint32)domain->last_seq_check));

	return NT_STATUS_OK;
}
示例#11
0
文件: reg_db.c 项目: AllardJ/Tomato
int regdb_fetch_values( const char* key, REGVAL_CTR *values )
{
	TDB_DATA data;
	pstring keystr;

	DEBUG(10,("regdb_fetch_values: Looking for value of key [%s] \n", key));
	
	pstr_sprintf( keystr, "%s/%s", VALUE_PREFIX, key );
	normalize_reg_path( keystr );
	
	data = tdb_fetch_bystring( tdb_reg, keystr );
	
	if ( !data.dptr ) {
		/* all keys have zero values by default */
		return 0;
	}
	
	regdb_unpack_values( values, data.dptr, data.dsize );
	
	SAFE_FREE( data.dptr );
	
	return regval_ctr_numvals(values);
}
示例#12
0
文件: notify.c 项目: Arkhont/samba
/*
  load the notify array
*/
static NTSTATUS notify_load(struct notify_context *notify)
{
	TDB_DATA dbuf;
	DATA_BLOB blob;
	enum ndr_err_code ndr_err;
	int seqnum;

	seqnum = tdb_get_seqnum(notify->w->tdb);

	if (seqnum == notify->seqnum && notify->array != NULL) {
		return NT_STATUS_OK;
	}

	notify->seqnum = seqnum;

	talloc_free(notify->array);
	notify->array = talloc_zero(notify, struct notify_array);
	NT_STATUS_HAVE_NO_MEMORY(notify->array);

	dbuf = tdb_fetch_bystring(notify->w->tdb, NOTIFY_KEY);
	if (dbuf.dptr == NULL) {
		return NT_STATUS_OK;
	}

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

	ndr_err = ndr_pull_struct_blob(&blob, notify->array, notify->array,
				       (ndr_pull_flags_fn_t)ndr_pull_notify_array);
	free(dbuf.dptr);
	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
		return ndr_map_error2ntstatus(ndr_err);
	}

	return NT_STATUS_OK;
}
示例#13
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;
}
示例#14
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;
}
示例#15
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;
}
示例#16
0
文件: registry.c 项目: sangfo/WMI_cmd
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;
}
示例#17
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;
}
示例#18
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);
}
示例#19
0
文件: vlp.c 项目: 0x24bin/winexe-1
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;
}
示例#20
0
static
NTSTATUS schannel_fetch_session_key_tdb(struct tdb_wrap *tdb_sc,
					TALLOC_CTX *mem_ctx,
					const char *computer_name,
					struct netlogon_creds_CredentialState **pcreds)
{
	NTSTATUS status;
	TDB_DATA value;
	enum ndr_err_code ndr_err;
	DATA_BLOB blob;
	struct netlogon_creds_CredentialState *creds = NULL;
	char *keystr = NULL;
	char *name_upper;

	*pcreds = NULL;

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

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

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

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

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

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

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

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

	status = NT_STATUS_OK;

 done:

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

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

	*pcreds = creds;

	return NT_STATUS_OK;
}