Exemple #1
0
/* 
   called when a client connects to a share
*/
static int tsmsm_connect(struct vfs_handle_struct *handle,
			 const char *service,
			 const char *user) {
	struct tsmsm_struct *tsmd;
	const char *fres;
	const char *tsmname;
        int ret = SMB_VFS_NEXT_CONNECT(handle, service, user);

	if (ret < 0) {
		return ret;
	}

	tsmd = talloc_zero(handle, struct tsmsm_struct);
	if (!tsmd) {
		SMB_VFS_NEXT_DISCONNECT(handle);
		DEBUG(0,("tsmsm_connect: out of memory!\n"));
		return -1;
	}

	if (!dmapi_have_session()) {
		SMB_VFS_NEXT_DISCONNECT(handle);
		DEBUG(0,("tsmsm_connect: no DMAPI session for Samba is available!\n"));
		TALLOC_FREE(tsmd);
		return -1;
	}

	tsmname = (handle->param ? handle->param : "tsmsm");
	
	/* Get 'hsm script' and 'dmapi attribute' parameters to tsmd context */
	tsmd->hsmscript = lp_parm_talloc_string(SNUM(handle->conn), tsmname,
						"hsm script", NULL);
	talloc_steal(tsmd, tsmd->hsmscript);
	
	tsmd->attrib_name = lp_parm_talloc_string(SNUM(handle->conn), tsmname, 
						  "dmapi attribute", DM_ATTRIB_OBJECT);
	talloc_steal(tsmd, tsmd->attrib_name);
	
	tsmd->attrib_value = lp_parm_talloc_string(SNUM(handle->conn), "tsmsm", 
						   "dmapi value", NULL);
	talloc_steal(tsmd, tsmd->attrib_value);
	
	/* retrieve 'online ratio'. In case of error default to FILE_IS_ONLINE_RATIO */
	fres = lp_parm_const_string(SNUM(handle->conn), tsmname, 
				    "online ratio", NULL);
	if (fres == NULL) {
		tsmd->online_ratio = FILE_IS_ONLINE_RATIO;
	} else {
		tsmd->online_ratio = strtof(fres, NULL);
		if (tsmd->online_ratio > 1.0 ||
		    tsmd->online_ratio <= 0.0) {
			DEBUG(1, ("tsmsm_connect: invalid online ration %f - using %f.\n",
				  tsmd->online_ratio, (float)FILE_IS_ONLINE_RATIO));
		}
	}

        /* Store the private data. */
        SMB_VFS_HANDLE_SET_DATA(handle, tsmd, tsmsm_free_data,
                                struct tsmsm_struct, return -1);
        return 0;
}
Exemple #2
0
/*
  open the permanent tdb
 */
static NTSTATUS idmap_tdb2_open_db(void)
{
	char *db_path;
	
	if (idmap_tdb2) {
		/* its already open */
		return NT_STATUS_OK;
	}

	db_path = lp_parm_talloc_string(-1, "tdb", "idmap2.tdb", NULL);
	if (db_path == NULL) {
		/* fall back to the private directory, which, despite
		   its name, is usually on shared storage */
		db_path = talloc_asprintf(NULL, "%s/idmap2.tdb", lp_private_dir());
	}
	NT_STATUS_HAVE_NO_MEMORY(db_path);

	/* Open idmap repository */
	idmap_tdb2 = db_open(NULL, db_path, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0644);
	TALLOC_FREE(db_path);

	if (idmap_tdb2 == NULL) {
		DEBUG(0, ("Unable to open idmap_tdb2 database '%s'\n",
			  db_path));
		return NT_STATUS_UNSUCCESSFUL;
	}

	/* load the ranges and high/low water marks */
	return idmap_tdb2_alloc_load();
}
Exemple #3
0
static DATA_BLOB negprot_spnego(void)
{
	DATA_BLOB blob;
	nstring dos_name;
	fstring unix_name;
#ifdef DEVELOPER
	size_t slen;
#endif
	char guid[17];
	const char *OIDs_krb5[] = {OID_KERBEROS5,
				   OID_KERBEROS5_OLD,
				   OID_NTLMSSP,
				   NULL};
	const char *OIDs_plain[] = {OID_NTLMSSP, NULL};

	global_spnego_negotiated = True;

	memset(guid, '\0', sizeof(guid));

	safe_strcpy(unix_name, global_myname(), sizeof(unix_name)-1);
	strlower_m(unix_name);
	push_ascii_nstring(dos_name, unix_name);
	safe_strcpy(guid, dos_name, sizeof(guid)-1);

#ifdef DEVELOPER
	/* Fix valgrind 'uninitialized bytes' issue. */
	slen = strlen(dos_name);
	if (slen < sizeof(guid)) {
		memset(guid+slen, '\0', sizeof(guid) - slen);
	}
#endif

	/* strangely enough, NT does not sent the single OID NTLMSSP when
	   not a ADS member, it sends no OIDs at all

	   OLD COMMENT : "we can't do this until we teach our sesssion setup parser to know
		   about raw NTLMSSP (clients send no ASN.1 wrapping if we do this)"

	   Our sessionsetup code now handles raw NTLMSSP connects, so we can go
	   back to doing what W2K3 does here. This is needed to make PocketPC 2003
	   CIFS connections work with SPNEGO. See bugzilla bugs #1828 and #3133
	   for details. JRA.

	*/

	if (lp_security() != SEC_ADS && !lp_use_kerberos_keytab()) {
#if 0
		/* Code for PocketPC client */
		blob = data_blob(guid, 16);
#else
		/* Code for standalone WXP client */
		blob = spnego_gen_negTokenInit(guid, OIDs_plain, "NONE");
#endif
	} else {
		fstring myname;
		char *host_princ_s = NULL;

		const char * lkdc_realm =
			lp_parm_talloc_string(GLOBAL_SECTION_SNUM,
				"com.apple", "lkdc realm", NULL);

		myname[0] = '\0';
		get_mydnsfullname(myname);
		strlower_m(myname);

		/* If we have a LKDC, use it unless there is a managed realm
		 * also configured. The managed realm should have precedence.
		 */
		if (lkdc_realm && (*lp_realm() == '\0' ||
				strcmp(lkdc_realm, lp_realm()) == 0)) {
			asprintf(&host_princ_s,
				"cifs/%s@%s", lkdc_realm, lkdc_realm);
		} else {
			asprintf(&host_princ_s, "cifs/%s@%s",
					myname, lp_realm());
		}

		blob = spnego_gen_negTokenInit(guid, OIDs_krb5, host_princ_s);

		SAFE_FREE(host_princ_s);
		TALLOC_FREE(lkdc_realm);
	}

	return blob;
}
Exemple #4
0
static BOOL ads_keytab_verify_ticket(krb5_context context,
					krb5_auth_context auth_context,
					const DATA_BLOB *ticket,
					krb5_ticket **pp_tkt,
					krb5_keyblock **keyblock,
					krb5_error_code *perr)
{
	krb5_error_code ret = 0;
	BOOL auth_ok = False;
	krb5_keytab keytab = NULL;
	krb5_kt_cursor kt_cursor;
	krb5_keytab_entry kt_entry;
	char *valid_princ_formats[9];
	fstring my_name, my_fqdn;
	int i;

	const char * lkdc_realm = lp_parm_talloc_string(GLOBAL_SECTION_SNUM,
					"com.apple", "lkdc realm", NULL);

	ZERO_ARRAY(valid_princ_formats);

	*pp_tkt = NULL;
	*keyblock = NULL;
	*perr = 0;

	/* Generate the list of principal names which we expect
	 * clients might want to use for authenticating to the file
	 * service.  We allow name$,{host,cifs}/{name,fqdn,name.REALM}. */

	fstrcpy(my_name, global_myname());

	my_fqdn[0] = '\0';
	get_mydnsfullname(my_fqdn);

	asprintf(&valid_princ_formats[0], "%s$@%s", my_name, lp_realm());
	asprintf(&valid_princ_formats[1], "host/%s@%s", my_name, lp_realm());
	asprintf(&valid_princ_formats[2], "host/%s@%s", my_fqdn, lp_realm());
	asprintf(&valid_princ_formats[3], "host/%s.%s@%s", my_name, lp_realm(), lp_realm());
	asprintf(&valid_princ_formats[4], "cifs/%s@%s", my_name, lp_realm());
	asprintf(&valid_princ_formats[5], "cifs/%s@%s", my_fqdn, lp_realm());
	asprintf(&valid_princ_formats[6], "cifs/%s.%s@%s", my_name, lp_realm(), lp_realm());

	if (lkdc_realm) {
		asprintf(&valid_princ_formats[7],
			"host/%s@%s", lkdc_realm, lkdc_realm);
		asprintf(&valid_princ_formats[8],
			"cifs/%s@%s", lkdc_realm, lkdc_realm);
	}

	for (i = 0; i < ARRAY_SIZE(valid_princ_formats); i++) {

		ZERO_STRUCT(kt_entry);
		ZERO_STRUCT(kt_cursor);

		ret = krb5_kt_default(context, &keytab);
		if (ret) {
			DEBUG(1, ("ads_keytab_verify_ticket: krb5_kt_default failed (%s)\n", error_message(ret)));
			goto out;
		}

		/* Iterate through the keytab.  For each key, if the principal
		 * name case-insensitively matches one of the allowed formats,
		 * try verifying the ticket using that principal.
		 */

		ret = krb5_kt_start_seq_get(context, keytab, &kt_cursor);
		if (ret) {
			DEBUG(1, ("ads_keytab_verify_ticket: krb5_kt_start_seq_get failed (%s)\n", error_message(ret)));
			goto out;
		}

		while (!auth_ok && (krb5_kt_next_entry(context, keytab, &kt_entry, &kt_cursor) == 0)) {

			/* In MIT Kerberos, it is not legal to interleave krb5_rd_req()
			 * with krb5_kt_start_seq_get() and krb5_kt_end_seq_get() on the
			 * same krb5_keytab object. We have to keep a separate
			 * krb5_keytab object around for the krb5_rd_req().
			 */
			ret = ads_keytab_verify_for_principal(context,
				auth_context, &kt_entry, ticket,
				valid_princ_formats[i], pp_tkt, keyblock);

			if (ret == 0) {
				auth_ok = True;
			}

			/* Free the entry we just read. */
			smb_krb5_kt_free_entry(context, &kt_entry);
			ZERO_STRUCT(kt_entry);

			if (auth_ok) {
				/* success, let's go. */
				break;
			}

			/* workaround for MIT:
			* as krb5_ktfile_get_entry will explicitly
			* close the krb5_keytab as soon as krb5_rd_req
			* has sucessfully decrypted the ticket but the
			* ticket is not valid yet (due to clockskew)
			* there is no point in querying more keytab
			* entries - Guenther */
			if (ret == KRB5KRB_AP_ERR_TKT_NYV ||
			    ret == KRB5KRB_AP_ERR_TKT_EXPIRED ||
			    ret == KRB5KRB_AP_ERR_SKEW ||
			    ret == KRB5KRB_AP_ERR_REPEAT) {
			    break;
			}

		}

		krb5_kt_end_seq_get(context, keytab, &kt_cursor);
		krb5_kt_close(context, keytab);
		keytab = NULL;
	}

	ZERO_STRUCT(kt_cursor);

out:

	TALLOC_FREE(lkdc_realm);

	for (i = 0; i < ARRAY_SIZE(valid_princ_formats); i++) {
		SAFE_FREE(valid_princ_formats[i]);
	}

	{
		krb5_keytab_entry zero_kt_entry;
		ZERO_STRUCT(zero_kt_entry);
		if (memcmp(&zero_kt_entry, &kt_entry, sizeof(krb5_keytab_entry))) {
			smb_krb5_kt_free_entry(context, &kt_entry);
		}
	}

	{
		krb5_kt_cursor zero_csr;
		ZERO_STRUCT(zero_csr);
		if ((memcmp(&kt_cursor, &zero_csr, sizeof(krb5_kt_cursor)) != 0) && keytab) {
			krb5_kt_end_seq_get(context, keytab, &kt_cursor);
		}
	}

	if (keytab) {
		krb5_kt_close(context, keytab);
	}
	*perr = ret;
	return auth_ok;
}
static int nfs4acl_connect(struct vfs_handle_struct *handle,
			   const char *service,
			   const char *user)
{
	struct nfs4acl_config *config = NULL;
	const struct enum_list *default_acl_style_list = NULL;
	const char *default_xattr_name = NULL;
	int enumval;
	unsigned nfs_version;
	int ret;

	default_acl_style_list = get_default_acl_style_list();

	config = talloc_zero(handle->conn, struct nfs4acl_config);
	if (config == NULL) {
		DBG_ERR("talloc_zero() failed\n");
		return -1;
	}

	ret = SMB_VFS_NEXT_CONNECT(handle, service, user);
	if (ret < 0) {
		TALLOC_FREE(config);
		return ret;
	}

	ret = smbacl4_get_vfs_params(handle->conn, &config->nfs4_params);
	if (ret < 0) {
		TALLOC_FREE(config);
		return ret;
	}

	enumval = lp_parm_enum(SNUM(handle->conn),
			       "nfs4acl_xattr",
			       "encoding",
			       nfs4acl_encoding,
			       NFS4ACL_ENCODING_NDR);
	if (enumval == -1) {
		DBG_ERR("Invalid \"nfs4acl_xattr:encoding\" parameter\n");
		return -1;
	}
	config->encoding = (enum nfs4acl_encoding)enumval;

	switch (config->encoding) {
	case NFS4ACL_ENCODING_XDR:
		default_xattr_name = NFS4ACL_XDR_XATTR_NAME;
		break;
	case NFS4ACL_ENCODING_NDR:
	default:
		default_xattr_name = NFS4ACL_NDR_XATTR_NAME;
		break;
	}

	nfs_version = (unsigned)lp_parm_int(SNUM(handle->conn),
					    "nfs4acl_xattr",
					    "version",
					    41);
	switch (nfs_version) {
	case 40:
		config->nfs_version = ACL4_XATTR_VERSION_40;
		break;
	case 41:
		config->nfs_version = ACL4_XATTR_VERSION_41;
		break;
	default:
		config->nfs_version = ACL4_XATTR_VERSION_DEFAULT;
		break;
	}

	config->default_acl_style = lp_parm_enum(SNUM(handle->conn),
						 "nfs4acl_xattr",
						 "default acl style",
						 default_acl_style_list,
						 DEFAULT_ACL_EVERYONE);

	config->xattr_name = lp_parm_talloc_string(config,
						   SNUM(handle->conn),
						   "nfs4acl_xattr",
						   "xattr_name",
						   default_xattr_name);

	SMB_VFS_HANDLE_SET_DATA(handle, config, NULL, struct nfs4acl_config,
				return -1);

	/*
	 * Ensure we have the parameters correct if we're using this module.
	 */
	DBG_NOTICE("Setting 'inherit acls = true', "
		   "'dos filemode = true', "
		   "'force unknown acl user = true', "
		   "'create mask = 0666', "
		   "'directory mask = 0777' and "
		   "'store dos attributes = yes' "
		   "for service [%s]\n", service);

	lp_do_parameter(SNUM(handle->conn), "inherit acls", "true");
	lp_do_parameter(SNUM(handle->conn), "dos filemode", "true");
	lp_do_parameter(SNUM(handle->conn), "force unknown acl user", "true");
	lp_do_parameter(SNUM(handle->conn), "create mask", "0666");
	lp_do_parameter(SNUM(handle->conn), "directory mask", "0777");
	lp_do_parameter(SNUM(handle->conn), "store dos attributes", "yes");

	return 0;
}