Example #1
0
void gencache_iterate(void (*fn)(const char* key, const char *value, time_t timeout, void* dptr),
                      void* data, const char* keystr_pattern)
{
	TDB_LIST_NODE *node, *first_node;
	TDB_DATA databuf;
	char *keystr = NULL, *valstr = NULL, *entry = NULL;
	time_t timeout = 0;

	/* fail completely if get null pointers passed */
	SMB_ASSERT(fn && keystr_pattern);

	if (!gencache_init()) return;

	DEBUG(5, ("Searching cache keys with pattern %s\n", keystr_pattern));
	node = tdb_search_keys(cache, keystr_pattern);
	first_node = node;
	
	while (node) {
		/* ensure null termination of the key string */
		keystr = SMB_STRNDUP(node->node_key.dptr, node->node_key.dsize);
		
		/* 
		 * We don't use gencache_get function, because we need to iterate through
		 * all of the entries. Validity verification is up to fn routine.
		 */
		databuf = tdb_fetch(cache, node->node_key);
		if (!databuf.dptr || databuf.dsize <= TIMEOUT_LEN) {
			SAFE_FREE(databuf.dptr);
			SAFE_FREE(keystr);
			node = node->next;
			continue;
		}
		entry = SMB_STRNDUP(databuf.dptr, databuf.dsize);
		SAFE_FREE(databuf.dptr);
		valstr = SMB_MALLOC(databuf.dsize - TIMEOUT_LEN);
		sscanf(entry, CACHE_DATA_FMT, (int*)(&timeout), valstr);
		
		DEBUG(10, ("Calling function with arguments (key = %s, value = %s, timeout = %s)\n",
		           keystr, valstr, ctime(&timeout)));
		fn(keystr, valstr, timeout, data);
		
		SAFE_FREE(valstr);
		SAFE_FREE(entry);
		SAFE_FREE(keystr);
		node = node->next;
	}
	
	tdb_search_list_free(first_node);
}
Example #2
0
BOOL gencache_get(const char *keystr, char **valstr, time_t *timeout)
{
	TDB_DATA keybuf, databuf;

	/* fail completely if get null pointers passed */
	SMB_ASSERT(keystr);

	if (!gencache_init())
		return False;
	
	keybuf.dptr = SMB_STRDUP(keystr);
	keybuf.dsize = strlen(keystr)+1;
	databuf = tdb_fetch(cache, keybuf);
	SAFE_FREE(keybuf.dptr);
	
	if (databuf.dptr && databuf.dsize > TIMEOUT_LEN) {
		char* entry_buf = SMB_STRNDUP(databuf.dptr, databuf.dsize);
		char *v;
		time_t t;

		v = SMB_MALLOC(databuf.dsize - TIMEOUT_LEN);
				
		SAFE_FREE(databuf.dptr);
		sscanf(entry_buf, CACHE_DATA_FMT, (int*)&t, v);
		SAFE_FREE(entry_buf);

		DEBUG(10, ("Returning %s cache entry: key = %s, value = %s, "
			   "timeout = %s\n", t > time(NULL) ? "valid" :
			   "expired", keystr, v, ctime(&t)));

		if (valstr)
			*valstr = v;
		else
			SAFE_FREE(v);

		if (timeout)
			*timeout = t;

		return t > time(NULL);

	} else {
		SAFE_FREE(databuf.dptr);

		if (valstr)
			*valstr = NULL;

		if (timeout)
			timeout = NULL;

		DEBUG(10, ("Cache entry with key = %s couldn't be found\n", 
			   keystr));

		return False;
	}
}
Example #3
0
/*
  insert an entry into the prefix cache. The string might not be null
  terminated */
static void cache_insert(const char *prefix, int length, u32 hash)
{
	int i = hash % MANGLE_CACHE_SIZE;

	if (prefix_cache[i]) {
		free(prefix_cache[i]);
	}

	prefix_cache[i] = SMB_STRNDUP(prefix, length);
	prefix_cache_hashes[i] = hash;
}
Example #4
0
/*
  insert an entry into the prefix cache. The string might not be null
  terminated */
static void cache_insert(const char *prefix, int length, unsigned int hash)
{
	char *str = SMB_STRNDUP(prefix, length);

	if (str == NULL) {
		return;
	}

	memcache_add(smbd_memcache(), MANGLE_HASH2_CACHE,
		     data_blob_const(&hash, sizeof(hash)),
		     data_blob_const(str, length+1));
	SAFE_FREE(str);
}
Example #5
0
static void get_auth_data(const char *srv, const char *shr, char *wg, int wglen, char *un, int unlen, char *pw, int pwlen)
{
	static char hasasked = 0;
	char *wgtmp, *usertmp;
	char tmp[128];

	if(hasasked) return;
	hasasked = 1;

	if(!nonprompt && !username) {
		printf("Username for %s at %s [guest] ", shr, srv);
		if (fgets(tmp, sizeof(tmp), stdin) == NULL) {
			return;
		}
		if ((strlen(tmp) > 0) && (tmp[strlen(tmp)-1] == '\n')) {
			tmp[strlen(tmp)-1] = '\0';
		}
		strncpy(un, tmp, unlen-1);
	} else if(username) strncpy(un, username, unlen-1);

	if(!nonprompt && !password) {
		char *prompt, *pass;
		if (asprintf(&prompt, "Password for %s at %s: ", shr, srv) == -1) {
			return;
		}
		pass = getpass(prompt);
		free(prompt);
		strncpy(pw, pass, pwlen-1);
	} else if(password) strncpy(pw, password, pwlen-1);

	if(workgroup)strncpy(wg, workgroup, wglen-1);

	wgtmp = SMB_STRNDUP(wg, wglen); 
	usertmp = SMB_STRNDUP(un, unlen);
	if(!quiet)printf("Using workgroup %s, %s%s\n", wgtmp, *usertmp?"user ":"******", usertmp);
	free(wgtmp); free(usertmp);
}
Example #6
0
/**
 * Parse text representation of timeout value
 *
 * @param timeout_str string containing text representation of the timeout
 * @return numeric timeout of time_t type
 **/
static time_t parse_timeout(const char* timeout_str)
{
	char sign = '\0', *number = NULL, unit = '\0';
	int len, number_begin, number_end;
	time_t timeout;

	/* sign detection */
	if (timeout_str[0] == '!' || timeout_str[0] == '+') {
		sign = timeout_str[0];
		number_begin = 1;
	} else {
		number_begin = 0;
	}
	
	/* unit detection */
	len = strlen(timeout_str);
	switch (timeout_str[len - 1]) {
	case 's':
	case 'm':
	case 'h':
	case 'd':
	case 'w': unit = timeout_str[len - 1];
	}
	
	/* number detection */
	len = (sign) ? strlen(&timeout_str[number_begin]) : len;
	number_end = (unit) ? len - 1 : len;
	number = SMB_STRNDUP(&timeout_str[number_begin], number_end);
	
	/* calculate actual timeout value */
	timeout = (time_t)atoi(number);

	switch (unit) {
	case 'm': timeout *= 60; break;
	case 'h': timeout *= 60*60; break;
	case 'd': timeout *= 60*60*24; break;
	case 'w': timeout *= 60*60*24*7; break;  /* that's fair enough, I think :) */
	}
	
	switch (sign) {
	case '!': timeout = time(NULL) - timeout; break;
	case '+':
	default:  timeout += time(NULL); break;
	}
	
	if (number) SAFE_FREE(number);
	return timeout;	
}
Example #7
0
static bool set_my_netbios_names(const char *name, int i)
{
	SAFE_FREE(smb_my_netbios_names[i]);

	/*
	 * Don't include space for terminating '\0' in strndup,
	 * it is automatically added. This screws up if the name
	 * is greater than MAX_NETBIOSNAME_LEN-1 in the unix
	 * charset, but less than or equal to MAX_NETBIOSNAME_LEN-1
	 * in the DOS charset, but this is so old we have to live
	 * with that.
	 */
	smb_my_netbios_names[i] = SMB_STRNDUP(name, MAX_NETBIOSNAME_LEN-1);
	if (!smb_my_netbios_names[i])
		return False;
	return strupper_m(smb_my_netbios_names[i]);
}
Example #8
0
static void print_progress(const char *name, time_t start, time_t now, off_t start_pos, off_t pos, off_t total)
{
	double avg = 0.0;
	long  eta = -1; 
	double prcnt = 0.0;
	char hpos[20], htotal[20], havg[20];
	char *status, *filename;
	int len;
	if(now - start)avg = 1.0 * (pos - start_pos) / (now - start);
	eta = (total - pos) / avg;
	if(total)prcnt = 100.0 * pos / total;

	human_readable(pos, hpos, sizeof(hpos));
	human_readable(total, htotal, sizeof(htotal));
	human_readable(avg, havg, sizeof(havg));

	len = asprintf(&status, "%s of %s (%.2f%%) at %s/s ETA: %s", hpos, htotal, prcnt, havg, print_time(eta));
	if (len == -1) {
		return;
	}
	
	if(columns) {
		int required = strlen(name), available = columns - len - strlen("[] ");
		if(required > available) {
			if (asprintf(&filename, "...%s", name + required - available + 3) == -1) {
				return;
			}
		} else {
			filename = SMB_STRNDUP(name, available);
		}
	} else filename = SMB_STRDUP(name);

	fprintf(stderr, "\r[%s] %s", filename, status);

	free(filename); free(status);
}
Example #9
0
static void manage_client_ntlmssp_request(enum stdio_helper_mode stdio_helper_mode, 
					 char *buf, int length) 
{
	static NTLMSSP_STATE *ntlmssp_state = NULL;
	DATA_BLOB request, reply;
	NTSTATUS nt_status;
	BOOL first = False;
	
	if (strlen(buf) < 2) {
		DEBUG(1, ("NTLMSSP query [%s] invalid", buf));
		x_fprintf(x_stdout, "BH\n");
		return;
	}

	if (strlen(buf) > 3) {
		request = base64_decode_data_blob(buf + 3);
	} else {
		request = data_blob(NULL, 0);
	}

	if (strncmp(buf, "PW ", 3) == 0) {
		/* We asked for a password and obviously got it :-) */

		opt_password = SMB_STRNDUP((const char *)request.data, request.length);

		if (opt_password == NULL) {
			DEBUG(1, ("Out of memory\n"));
			x_fprintf(x_stdout, "BH\n");
			data_blob_free(&request);
			return;
		}

		x_fprintf(x_stdout, "OK\n");
		data_blob_free(&request);
		return;
	}

	if (opt_password == NULL) {
		
		/* Request a password from the calling process.  After
		   sending it, the calling process should retry asking for the negotiate. */
		
		DEBUG(10, ("Requesting password\n"));
		x_fprintf(x_stdout, "PW\n");
		return;
	}

	if (strncmp(buf, "YR", 2) == 0) {
		if (ntlmssp_state)
			ntlmssp_end(&ntlmssp_state);
	} else if (strncmp(buf, "TT", 2) == 0) {
		
	} else {
		DEBUG(1, ("NTLMSSP query [%s] invalid", buf));
		x_fprintf(x_stdout, "BH\n");
		return;
	}

	if (!ntlmssp_state) {
		if (!NT_STATUS_IS_OK(nt_status = ntlm_auth_start_ntlmssp_client(&ntlmssp_state))) {
			x_fprintf(x_stdout, "BH %s\n", nt_errstr(nt_status));
			return;
		}
		first = True;
	}

	DEBUG(10, ("got NTLMSSP packet:\n"));
	dump_data(10, (const char *)request.data, request.length);

	nt_status = ntlmssp_update(ntlmssp_state, request, &reply);
	
	if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
		char *reply_base64 = base64_encode_data_blob(reply);
		if (first) {
			x_fprintf(x_stdout, "YR %s\n", reply_base64);
		} else { 
			x_fprintf(x_stdout, "KK %s\n", reply_base64);
		}
		SAFE_FREE(reply_base64);
		data_blob_free(&reply);
		DEBUG(10, ("NTLMSSP challenge\n"));
	} else if (NT_STATUS_IS_OK(nt_status)) {
		char *reply_base64 = base64_encode_data_blob(reply);
		x_fprintf(x_stdout, "AF %s\n", reply_base64);
		SAFE_FREE(reply_base64);
		DEBUG(10, ("NTLMSSP OK!\n"));
		if (ntlmssp_state)
			ntlmssp_end(&ntlmssp_state);
	} else {
		x_fprintf(x_stdout, "BH %s\n", nt_errstr(nt_status));
		DEBUG(0, ("NTLMSSP BH: %s\n", nt_errstr(nt_status)));
		if (ntlmssp_state)
			ntlmssp_end(&ntlmssp_state);
	}

	data_blob_free(&request);
}
Example #10
0
static void manage_squid_ntlmssp_request(enum stdio_helper_mode stdio_helper_mode, 
					 char *buf, int length) 
{
	static NTLMSSP_STATE *ntlmssp_state = NULL;
	DATA_BLOB request, reply;
	NTSTATUS nt_status;

	if (strlen(buf) < 2) {
		DEBUG(1, ("NTLMSSP query [%s] invalid", buf));
		x_fprintf(x_stdout, "BH\n");
		return;
	}

	if (strlen(buf) > 3) {
		request = base64_decode_data_blob(buf + 3);
	} else {
		request = data_blob(NULL, 0);
	}

	if ((strncmp(buf, "PW ", 3) == 0)) {
		/* The calling application wants us to use a local password (rather than winbindd) */

		opt_password = SMB_STRNDUP((const char *)request.data, request.length);

		if (opt_password == NULL) {
			DEBUG(1, ("Out of memory\n"));
			x_fprintf(x_stdout, "BH\n");
			data_blob_free(&request);
			return;
		}

		x_fprintf(x_stdout, "OK\n");
		data_blob_free(&request);
		return;
	}

	if (strncmp(buf, "YR", 2) == 0) {
		if (ntlmssp_state)
			ntlmssp_end(&ntlmssp_state);
	} else if (strncmp(buf, "KK", 2) == 0) {
		
	} else {
		DEBUG(1, ("NTLMSSP query [%s] invalid", buf));
		x_fprintf(x_stdout, "BH\n");
		return;
	}

	if (!ntlmssp_state) {
		if (!NT_STATUS_IS_OK(nt_status = ntlm_auth_start_ntlmssp_server(&ntlmssp_state))) {
			x_fprintf(x_stdout, "BH %s\n", nt_errstr(nt_status));
			return;
		}
	}

	DEBUG(10, ("got NTLMSSP packet:\n"));
	dump_data(10, (const char *)request.data, request.length);

	nt_status = ntlmssp_update(ntlmssp_state, request, &reply);
	
	if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
		char *reply_base64 = base64_encode_data_blob(reply);
		x_fprintf(x_stdout, "TT %s\n", reply_base64);
		SAFE_FREE(reply_base64);
		data_blob_free(&reply);
		DEBUG(10, ("NTLMSSP challenge\n"));
	} else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_ACCESS_DENIED)) {
		x_fprintf(x_stdout, "BH %s\n", nt_errstr(nt_status));
		DEBUG(0, ("NTLMSSP BH: %s\n", nt_errstr(nt_status)));

		ntlmssp_end(&ntlmssp_state);
	} else if (!NT_STATUS_IS_OK(nt_status)) {
		x_fprintf(x_stdout, "NA %s\n", nt_errstr(nt_status));
		DEBUG(10, ("NTLMSSP %s\n", nt_errstr(nt_status)));
	} else {
		x_fprintf(x_stdout, "AF %s\n", (char *)ntlmssp_state->auth_context);
		DEBUG(10, ("NTLMSSP OK!\n"));
	}

	data_blob_free(&request);
}
Example #11
0
static void manage_gss_spnego_client_request(enum stdio_helper_mode stdio_helper_mode, 
					     char *buf, int length) 
{
	DATA_BLOB request;
	SPNEGO_DATA spnego;
	ssize_t len;

	if (strlen(buf) <= 3) {
		DEBUG(1, ("SPNEGO query [%s] too short\n", buf));
		x_fprintf(x_stdout, "BH\n");
		return;
	}

	request = base64_decode_data_blob(buf+3);

	if (strncmp(buf, "PW ", 3) == 0) {

		/* We asked for a password and obviously got it :-) */

		opt_password = SMB_STRNDUP((const char *)request.data, request.length);
		
		if (opt_password == NULL) {
			DEBUG(1, ("Out of memory\n"));
			x_fprintf(x_stdout, "BH\n");
			data_blob_free(&request);
			return;
		}

		x_fprintf(x_stdout, "OK\n");
		data_blob_free(&request);
		return;
	}

	if ( (strncmp(buf, "TT ", 3) != 0) &&
	     (strncmp(buf, "AF ", 3) != 0) &&
	     (strncmp(buf, "NA ", 3) != 0) ) {
		DEBUG(1, ("SPNEGO request [%s] invalid\n", buf));
		x_fprintf(x_stdout, "BH\n");
		data_blob_free(&request);
		return;
	}

	/* So we got a server challenge to generate a SPNEGO
           client-to-server request... */

	len = read_spnego_data(request, &spnego);
	data_blob_free(&request);

	if (len == -1) {
		DEBUG(1, ("Could not read SPNEGO data for [%s]\n", buf));
		x_fprintf(x_stdout, "BH\n");
		return;
	}

	if (spnego.type == SPNEGO_NEG_TOKEN_INIT) {

		/* The server offers a list of mechanisms */

		const char **mechType = (const char **)spnego.negTokenInit.mechTypes;

		while (*mechType != NULL) {

#ifdef HAVE_KRB5
			if ( (strcmp(*mechType, OID_KERBEROS5_OLD) == 0) ||
			     (strcmp(*mechType, OID_KERBEROS5) == 0) ) {
				if (manage_client_krb5_init(spnego))
					goto out;
			}
#endif

			if (strcmp(*mechType, OID_NTLMSSP) == 0) {
				if (manage_client_ntlmssp_init(spnego))
					goto out;
			}

			mechType++;
		}

		DEBUG(1, ("Server offered no compatible mechanism\n"));
		x_fprintf(x_stdout, "BH\n");
		return;
	}

	if (spnego.type == SPNEGO_NEG_TOKEN_TARG) {

		if (spnego.negTokenTarg.supportedMech == NULL) {
			/* On accept/reject Windows does not send the
                           mechanism anymore. Handle that here and
                           shut down the mechanisms. */

			switch (spnego.negTokenTarg.negResult) {
			case SPNEGO_ACCEPT_COMPLETED:
				x_fprintf(x_stdout, "AF\n");
				break;
			case SPNEGO_REJECT:
				x_fprintf(x_stdout, "NA\n");
				break;
			default:
				DEBUG(1, ("Got a negTokenTarg with no mech and an "
					  "unknown negResult: %d\n",
					  spnego.negTokenTarg.negResult));
				x_fprintf(x_stdout, "BH\n");
			}

			ntlmssp_end(&client_ntlmssp_state);
			goto out;
		}

		if (strcmp(spnego.negTokenTarg.supportedMech,
			   OID_NTLMSSP) == 0) {
			manage_client_ntlmssp_targ(spnego);
			goto out;
		}

#if HAVE_KRB5
		if (strcmp(spnego.negTokenTarg.supportedMech,
			   OID_KERBEROS5_OLD) == 0) {
			manage_client_krb5_targ(spnego);
			goto out;
		}
#endif

	}

	DEBUG(1, ("Got an SPNEGO token I could not handle [%s]!\n", buf));
	x_fprintf(x_stdout, "BH\n");
	return;

 out:
	free_spnego_data(&spnego);
	return;
}
Example #12
0
/* search for a credcache that looks like a likely candidate */
static char *
find_krb5_cc(const char *dirname, uid_t uid)
{
	struct dirent **namelist;
	struct stat sbuf;
	char ccname[MAX_CCNAME_LEN], *credpath, *best_cache = NULL;
	int i, n;
	time_t cred_time, best_time = 0;

	n = scandir(dirname, &namelist, krb5cc_filter, NULL);
	if (n < 0) {
		syslog(LOG_DEBUG, "%s: scandir error on directory '%s': %s",
				  __func__, dirname, strerror(errno));
		return NULL;
	}

	for (i = 0; i < n; i++) {
		snprintf(ccname, sizeof(ccname), "FILE:%s/%s", dirname,
			 namelist[i]->d_name);
		credpath = ccname + 5;
		syslog(LOG_DEBUG, "%s: considering %s", __func__, credpath);

		if (lstat(credpath, &sbuf)) {
			syslog(LOG_DEBUG, "%s: stat error on '%s': %s",
					  __func__, credpath, strerror(errno));
			free(namelist[i]);
			continue;
		}
		if (sbuf.st_uid != uid) {
			syslog(LOG_DEBUG, "%s: %s is owned by %u, not %u",
					__func__, credpath, sbuf.st_uid, uid);
			free(namelist[i]);
			continue;
		}
		if (!S_ISREG(sbuf.st_mode)) {
			syslog(LOG_DEBUG, "%s: %s is not a regular file",
					__func__, credpath);
			free(namelist[i]);
			continue;
		}
		if (!(cred_time = get_tgt_time(ccname))) {
			syslog(LOG_DEBUG, "%s: %s is not a valid credcache.",
					__func__, ccname);
			free(namelist[i]);
			continue;
		}

		if (cred_time <= best_time) {
			syslog(LOG_DEBUG, "%s: %s expires sooner than current "
					  "best.", __func__, ccname);
			free(namelist[i]);
			continue;
		}

		syslog(LOG_DEBUG, "%s: %s is valid ccache", __func__, ccname);
		free(best_cache);
		best_cache = SMB_STRNDUP(ccname, MAX_CCNAME_LEN);
		best_time = cred_time;
		free(namelist[i]);
	}
	free(namelist);

	return best_cache;
}