Ejemplo n.º 1
0
static struct passwd *alloc_copy_passwd(const struct passwd *from) 
{
	struct passwd *ret = smb_xmalloc(sizeof(struct passwd));
	ZERO_STRUCTP(ret);
	ret->pw_name = smb_xstrdup(from->pw_name);
	ret->pw_passwd = smb_xstrdup(from->pw_passwd);
	ret->pw_uid = from->pw_uid;
	ret->pw_gid = from->pw_gid;
	ret->pw_gecos = smb_xstrdup(from->pw_gecos);
	ret->pw_dir = smb_xstrdup(from->pw_dir);
	ret->pw_shell = smb_xstrdup(from->pw_shell);
	return ret;
}
Ejemplo n.º 2
0
static void offer_gss_spnego_mechs(void) {

	DATA_BLOB token;
	SPNEGO_DATA spnego;
	ssize_t len;
	char *reply_base64;

	pstring principal;
	pstring myname_lower;

	ZERO_STRUCT(spnego);

	pstrcpy(myname_lower, global_myname());
	strlower_m(myname_lower);

	pstr_sprintf(principal, "%s$@%s", myname_lower, lp_realm());

	/* Server negTokenInit (mech offerings) */
	spnego.type = SPNEGO_NEG_TOKEN_INIT;
	spnego.negTokenInit.mechTypes = SMB_XMALLOC_ARRAY(const char *, 2);
#ifdef HAVE_KRB5
	spnego.negTokenInit.mechTypes[0] = smb_xstrdup(OID_KERBEROS5_OLD);
	spnego.negTokenInit.mechTypes[1] = smb_xstrdup(OID_NTLMSSP);
	spnego.negTokenInit.mechTypes[2] = NULL;
#else
	spnego.negTokenInit.mechTypes[0] = smb_xstrdup(OID_NTLMSSP);
	spnego.negTokenInit.mechTypes[1] = NULL;
#endif


	spnego.negTokenInit.mechListMIC = data_blob(principal,
						    strlen(principal));

	len = write_spnego_data(&token, &spnego);
	free_spnego_data(&spnego);

	if (len == -1) {
		DEBUG(1, ("Could not write SPNEGO data blob\n"));
		x_fprintf(x_stdout, "BH\n");
		return;
	}

	reply_base64 = base64_encode_data_blob(token);
	x_fprintf(x_stdout, "TT %s *\n", reply_base64);

	SAFE_FREE(reply_base64);
	data_blob_free(&token);
	DEBUG(10, ("sent SPNEGO negTokenInit\n"));
	return;
}
Ejemplo n.º 3
0
/* return true if access should be allowed */
bool allow_access(const char **deny_list,
		const char **allow_list,
		const char *cname,
		const char *caddr)
{
	bool ret;
	char *nc_cname = smb_xstrdup(cname);
	char *nc_caddr = smb_xstrdup(caddr);

	ret = allow_access_internal(deny_list, allow_list, nc_cname, nc_caddr);

	SAFE_FREE(nc_cname);
	SAFE_FREE(nc_caddr);
	return ret;
}
Ejemplo n.º 4
0
Archivo: auth.c Proyecto: sprymak/samba
NTSTATUS smb_register_auth(int version, const char *name, auth_init_function init)
{
	struct auth_init_function_entry *entry = auth_backends;

	if (version != AUTH_INTERFACE_VERSION) {
		DEBUG(0,("Can't register auth_method!\n"
			 "You tried to register an auth module with AUTH_INTERFACE_VERSION %d, while this version of samba uses %d\n",
			 version,AUTH_INTERFACE_VERSION));
		return NT_STATUS_OBJECT_TYPE_MISMATCH;
	}

	if (!name || !init) {
		return NT_STATUS_INVALID_PARAMETER;
	}

	DEBUG(5,("Attempting to register auth backend %s\n", name));

	if (auth_find_backend_entry(name)) {
		DEBUG(0,("There already is an auth method registered with the name %s!\n", name));
		return NT_STATUS_OBJECT_NAME_COLLISION;
	}

	entry = SMB_XMALLOC_P(struct auth_init_function_entry);
	entry->name = smb_xstrdup(name);
	entry->init = init;

	DLIST_ADD(auth_backends, entry);
	DEBUG(5,("Successfully added auth method '%s'\n", name));
	return NT_STATUS_OK;
}
Ejemplo n.º 5
0
static int rap_user_add(struct net_context *c, int argc, const char **argv)
{
	struct cli_state *cli;
	int ret;
	struct rap_user_info_1 userinfo;

	if (argc == 0 || c->display_usage) {
                return net_rap_user_usage(c, argc, argv);
	}

	if (!NT_STATUS_IS_OK(net_make_ipc_connection(c, 0, &cli)))
                return -1;

	strlcpy((char *)userinfo.user_name, argv[0], sizeof(userinfo.user_name));
	if (c->opt_flags == 0)
                c->opt_flags = 0x21;

	userinfo.userflags = c->opt_flags;
	userinfo.reserved1 = '\0';
        userinfo.comment = smb_xstrdup(c->opt_comment ? c->opt_comment : "");
	userinfo.priv = 1;
	userinfo.home_dir = NULL;
	userinfo.logon_script = NULL;
	userinfo.passwrd[0] = '\0';

	ret = cli_NetUserAdd(cli, &userinfo);

	cli_shutdown(cli);
	return ret;
}
Ejemplo n.º 6
0
Archivo: vfs.c Proyecto: hajuuk/R7000
NTSTATUS smb_register_vfs(int version, const char *name, vfs_op_tuple *vfs_op_tuples)
{
	struct vfs_init_function_entry *entry = backends;

 	if ((version != SMB_VFS_INTERFACE_VERSION)) {
		DEBUG(0, ("Failed to register vfs module.\n"
		          "The module was compiled against SMB_VFS_INTERFACE_VERSION %d,\n"
		          "current SMB_VFS_INTERFACE_VERSION is %d.\n"
		          "Please recompile against the current Samba Version!\n",  
			  version, SMB_VFS_INTERFACE_VERSION));
		return NT_STATUS_OBJECT_TYPE_MISMATCH;
  	}

	if (!name || !name[0] || !vfs_op_tuples) {
		DEBUG(0,("smb_register_vfs() called with NULL pointer or empty name!\n"));
		return NT_STATUS_INVALID_PARAMETER;
	}

	if (vfs_find_backend_entry(name)) {
		DEBUG(0,("VFS module %s already loaded!\n", name));
		return NT_STATUS_OBJECT_NAME_COLLISION;
	}

	entry = SMB_XMALLOC_P(struct vfs_init_function_entry);
	entry->name = smb_xstrdup(name);
	entry->vfs_op_tuples = vfs_op_tuples;

	DLIST_ADD(backends, entry);
	DEBUG(5, ("Successfully added vfs backend '%s'\n", name));
	return NT_STATUS_OK;
}
Ejemplo n.º 7
0
static bool parse_ntlm_auth_domain_user(const char *domuser, char **domain, 
										char **user, char winbind_separator)
{

	char *p = strchr(domuser, winbind_separator);

	if (!p) {
		return false;
	}
        
	*user = smb_xstrdup(p+1);
	*domain = smb_xstrdup(domuser);
	(*domain)[PTR_DIFF(p, domuser)] = 0;

	return true;
}
Ejemplo n.º 8
0
static int rap_user_add(int argc, const char **argv)
{
	struct cli_state *cli;
	int ret;
	RAP_USER_INFO_1 userinfo;

	if (argc == 0) {
		d_printf("\n\nUser name not specified\n");
                return net_rap_user_usage(argc, argv);
	}

	if (!(cli = net_make_ipc_connection(0)))
                return -1;
			
	safe_strcpy(userinfo.user_name, argv[0], sizeof(userinfo.user_name)-1);
	if (opt_flags == -1) 
                opt_flags = 0x21; 
			
	userinfo.userflags = opt_flags;
	userinfo.reserved1 = '\0';
	userinfo.comment = smb_xstrdup(opt_comment);
	userinfo.priv = 1; 
	userinfo.home_dir = NULL;
	userinfo.logon_script = NULL;

	ret = cli_NetUserAdd(cli, &userinfo);

	cli_shutdown(cli);
	return ret;
}
Ejemplo n.º 9
0
NTSTATUS smb_register_perfcounter(int interface_version, const char *name,
				  const struct smb_perfcount_handlers *handlers)
{
	struct smb_perfcount_module *entry = modules;

	if (interface_version != SMB_PERFCOUNTER_INTERFACE_VERSION) {
		DEBUG(0, ("Failed to register perfcount module.\n"
		          "The module was compiled against "
			  "SMB_PERFCOUNTER_INTERFACE_VERSION %d,\n"
		          "current SMB_PERFCOUNTER_INTERFACE_VERSION is %d.\n"
		          "Please recompile against the current Samba Version!\n",
			  interface_version, SMB_PERFCOUNTER_INTERFACE_VERSION));
		return NT_STATUS_OBJECT_TYPE_MISMATCH;
	}

	if (!name || !name[0] || !handlers) {
		DEBUG(0,("smb_register_perfcounter() called with NULL pointer "
			"or empty name!\n"));
		return NT_STATUS_INVALID_PARAMETER;
	}

	if (smb_perfcount_find_module(name)) {
		DEBUG(3,("Perfcount Module %s already loaded!\n", name));
		return NT_STATUS_OK;
	}

	entry = SMB_XMALLOC_P(struct smb_perfcount_module);
	entry->name = smb_xstrdup(name);
	entry->handlers = discard_const_p(struct smb_perfcount_handlers, handlers);

	DLIST_ADD(modules, entry);
	DEBUG(3, ("Successfully added perfcounter module '%s'\n", name));
	return NT_STATUS_OK;
}
Ejemplo n.º 10
0
Archivo: idmap.c Proyecto: hajuuk/R7000
NTSTATUS smb_register_idmap(int version, const char *name, struct idmap_methods *methods)
{
	struct idmap_function_entry *entry;

 	if ((version != SMB_IDMAP_INTERFACE_VERSION)) {
		DEBUG(0, ("smb_register_idmap: Failed to register idmap module.\n"
		          "The module was compiled against SMB_IDMAP_INTERFACE_VERSION %d,\n"
		          "current SMB_IDMAP_INTERFACE_VERSION is %d.\n"
		          "Please recompile against the current version of samba!\n",  
			  version, SMB_IDMAP_INTERFACE_VERSION));
		return NT_STATUS_OBJECT_TYPE_MISMATCH;
  	}

	if (!name || !name[0] || !methods) {
		DEBUG(0,("smb_register_idmap: called with NULL pointer or empty name!\n"));
		return NT_STATUS_INVALID_PARAMETER;
	}

	if (get_methods(name, False)) {
		DEBUG(0,("smb_register_idmap: idmap module %s already registered!\n", name));
		return NT_STATUS_OBJECT_NAME_COLLISION;
	}

	entry = SMB_XMALLOC_P(struct idmap_function_entry);
	entry->name = smb_xstrdup(name);
	entry->methods = methods;

	DLIST_ADD(backends, entry);
	DEBUG(5, ("smb_register_idmap: Successfully added idmap backend '%s'\n", name));
	return NT_STATUS_OK;
}
Ejemplo n.º 11
0
void add_session_workgroup(const char *workgroup)
{
	if (session_workgroup) {
		SAFE_FREE(session_workgroup);
	}
	session_workgroup = smb_xstrdup(workgroup);
}
Ejemplo n.º 12
0
/* return true if access should be allowed */
bool allow_access(const char **deny_list,
		const char **allow_list,
		const char *cname,
		const char *caddr)
{
	bool ret;
	char *nc_cname = smb_xstrdup(cname);
	char *nc_caddr = smb_xstrdup(caddr);

	ret = allow_access_internal(deny_list, allow_list, nc_cname, nc_caddr);

	DEBUG(ret ? 3 : 0,
	      ("%s connection from %s (%s)\n",
	       ret ? "Allowed" : "Denied", nc_cname, nc_caddr));

	SAFE_FREE(nc_cname);
	SAFE_FREE(nc_caddr);
	return ret;
}
Ejemplo n.º 13
0
NTSTATUS pdb_init_plugin(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
{
	void * dl_handle;
	char *plugin_location, *plugin_name, *p;
	pdb_init_function plugin_init;
	int (*plugin_version)(void);

	if (location == NULL) {
		DEBUG(0, ("The plugin module needs an argument!\n"));
		return NT_STATUS_UNSUCCESSFUL;
	}

	plugin_name = smb_xstrdup(location);
	p = strchr(plugin_name, ':');
	if (p) {
		*p = 0;
		plugin_location = p+1;
		trim_char(plugin_location, ' ', ' ');
	} else {
		plugin_location = NULL;
	}
	trim_char(plugin_name, ' ', ' ');

	DEBUG(5, ("Trying to load sam plugin %s\n", plugin_name));
	dl_handle = sys_dlopen(plugin_name, RTLD_NOW );
	if (!dl_handle) {
		DEBUG(0, ("Failed to load sam plugin %s using sys_dlopen (%s)\n", plugin_name, sys_dlerror()));
		return NT_STATUS_UNSUCCESSFUL;
	}
    
	plugin_version = sys_dlsym(dl_handle, "pdb_version");
	if (!plugin_version) {
		sys_dlclose(dl_handle);
		DEBUG(0, ("Failed to find function 'pdb_version' using sys_dlsym in sam plugin %s (%s)\n", plugin_name, sys_dlerror()));	    
		return NT_STATUS_UNSUCCESSFUL;
	}

	if (plugin_version() != PASSDB_INTERFACE_VERSION) {
		sys_dlclose(dl_handle);
		DEBUG(0, ("Wrong PASSDB_INTERFACE_VERSION! sam plugin has version %d and version %d is needed! Please update!\n",
			    plugin_version(),PASSDB_INTERFACE_VERSION));
		return NT_STATUS_UNSUCCESSFUL;
	}
				    	
	plugin_init = sys_dlsym(dl_handle, "pdb_init");
	if (!plugin_init) {
		sys_dlclose(dl_handle);
		DEBUG(0, ("Failed to find function 'pdb_init' using sys_dlsym in sam plugin %s (%s)\n", plugin_name, sys_dlerror()));	    
		return NT_STATUS_UNSUCCESSFUL;
	}

	DEBUG(5, ("Starting sam plugin %s with location %s\n", plugin_name, plugin_location));
	return plugin_init(pdb_context, pdb_method, plugin_location);
}
Ejemplo n.º 14
0
Archivo: auth.c Proyecto: sprymak/samba
bool load_auth_module(struct auth_context *auth_context, 
		      const char *module, auth_methods **ret) 
{
	static bool initialised_static_modules = False;

	struct auth_init_function_entry *entry;
	char *module_name = smb_xstrdup(module);
	char *module_params = NULL;
	char *p;
	bool good = False;

	/* Initialise static modules if not done so yet */
	if(!initialised_static_modules) {
		static_init_auth;
		initialised_static_modules = True;
	}

	DEBUG(5,("load_auth_module: Attempting to find an auth method to match %s\n",
		 module));

	p = strchr(module_name, ':');
	if (p) {
		*p = 0;
		module_params = p+1;
		trim_char(module_params, ' ', ' ');
	}

	trim_char(module_name, ' ', ' ');

	entry = auth_find_backend_entry(module_name);

	if (entry == NULL) {
		if (NT_STATUS_IS_OK(smb_probe_module("auth", module_name))) {
			entry = auth_find_backend_entry(module_name);
		}
	}

	if (entry != NULL) {
		if (!NT_STATUS_IS_OK(entry->init(auth_context, module_params, ret))) {
			DEBUG(0,("load_auth_module: auth method %s did not correctly init\n",
				 module_name));
		} else {
			DEBUG(5,("load_auth_module: auth method %s has a valid init\n",
				 module_name));
			good = True;
		}
	} else {
		DEBUG(0,("load_auth_module: can't find auth method %s!\n", module_name));
	}

	SAFE_FREE(module_name);
	return good;
}
Ejemplo n.º 15
0
Archivo: idmap.c Proyecto: hajuuk/R7000
BOOL idmap_init(const char **remote_backend)
{
	if (!backends)
		static_init_idmap;

	if (!cache_map) {
		cache_map = get_methods("tdb", True);

		if (!cache_map) {
			DEBUG(0, ("idmap_init: could not find tdb cache backend!\n"));
			return False;
		}
		
		if (!NT_STATUS_IS_OK(cache_map->init( NULL ))) {
			DEBUG(0, ("idmap_init: could not initialise tdb cache backend!\n"));
			return False;
		}
	}
	
	if ((remote_map == NULL) && (remote_backend != NULL) &&
	    (*remote_backend != NULL) && (**remote_backend != '\0'))  {
		char *rem_backend = smb_xstrdup(*remote_backend);
		fstring params = "";
		char *pparams;
		
		/* get any mode parameters passed in */
		
		if ( (pparams = strchr( rem_backend, ':' )) != NULL ) {
			*pparams = '\0';
			pparams++;
			fstrcpy( params, pparams );
		}
		
		DEBUG(3, ("idmap_init: using '%s' as remote backend\n", rem_backend));
		
		if((remote_map = get_methods(rem_backend, False)) ||
		    (NT_STATUS_IS_OK(smb_probe_module("idmap", rem_backend)) && 
		    (remote_map = get_methods(rem_backend, False)))) {
			if (!NT_STATUS_IS_OK(remote_map->init(params))) {
				DEBUG(0, ("idmap_init: failed to initialize remote backend!\n"));
				return False;
			}
		} else {
			DEBUG(0, ("idmap_init: could not load remote backend '%s'\n", rem_backend));
			SAFE_FREE(rem_backend);
			return False;
		}
		SAFE_FREE(rem_backend);
	}

	return True;
}
Ejemplo n.º 16
0
static void cm_get_ipc_userpass(char **username, char **domain, char **password)
{
	*username = secrets_fetch(SECRETS_AUTH_USER, NULL);
	*domain = secrets_fetch(SECRETS_AUTH_DOMAIN, NULL);
	*password = secrets_fetch(SECRETS_AUTH_PASSWORD, NULL);
	
	if (*username && **username) {

		if (!*domain || !**domain)
			*domain = smb_xstrdup(lp_workgroup());
		
		if (!*password || !**password)
			*password = smb_xstrdup("");

		DEBUG(3, ("cm_get_ipc_userpass: Retrieved auth-user from secrets.tdb [%s\\%s]\n", 
			  *domain, *username));

	} else {
		DEBUG(3, ("cm_get_ipc_userpass: No auth-user defined\n"));
		*username = smb_xstrdup("");
		*domain = smb_xstrdup("");
		*password = smb_xstrdup("");
	}
}
Ejemplo n.º 17
0
/**
 * check that a join is OK
 *
 * @return A shell status integer (0 for success)
 *
 **/
int net_rpc_testjoin(int argc, const char **argv) 
{
	char *domain = smb_xstrdup(opt_target_workgroup);

	/* Display success or failure */
	if (net_rpc_join_ok(domain) != 0) {
		fprintf(stderr,"Join to domain '%s' is not valid\n",domain);
		free(domain);
		return -1;
	}

	printf("Join to '%s' is OK\n",domain);
	free(domain);
	return 0;
}
Ejemplo n.º 18
0
/******************************************************************************
  When kerberos is not available, choose between anonymous or
  authenticated connections.

  We need to use an authenticated connection if DCs have the
  RestrictAnonymous registry entry set > 0, or the "Additional
  restrictions for anonymous connections" set in the win2k Local
  Security Policy.

  Caller to free() result in domain, username, password
*******************************************************************************/
void secrets_fetch_ipc_userpass(char **username, char **domain, char **password)
{
	*username = (char *)secrets_fetch(SECRETS_AUTH_USER, NULL);
	*domain = (char *)secrets_fetch(SECRETS_AUTH_DOMAIN, NULL);
	*password = (char *)secrets_fetch(SECRETS_AUTH_PASSWORD, NULL);

	if (*username && **username) {

		if (!*domain || !**domain)
			*domain = smb_xstrdup(lp_workgroup());

		if (!*password || !**password)
			*password = smb_xstrdup("");

		DEBUG(3, ("IPC$ connections done by user %s\\%s\n",
			  *domain, *username));

	} else {
		DEBUG(3, ("IPC$ connections done anonymously\n"));
		*username = smb_xstrdup("");
		*domain = smb_xstrdup("");
		*password = smb_xstrdup("");
	}
}
Ejemplo n.º 19
0
extern NTSTATUS mapiproxy_server_register(const void *_server_module)
{
	const struct mapiproxy_module	*server_module = (const struct mapiproxy_module *) _server_module;

	server_modules = realloc_p(server_modules, struct server_module, num_server_modules + 1);
	if (!server_modules) {
		smb_panic("out of memory in mapiproxy_server_register");
	}

	server_modules[num_server_modules].server_module = (struct mapiproxy_module *) smb_xmemdup(server_module, sizeof (*server_module));
	server_modules[num_server_modules].server_module->name = smb_xstrdup(server_module->name);

	num_server_modules++;

	DEBUG(3, ("MAPIPROXY server '%s' registered\n", server_module->name));

	return NT_STATUS_OK;
}
Ejemplo n.º 20
0
NTSTATUS register_rpc_module(struct rpc_module_fns *fns,
			     const char *name)
{
	struct rpc_module *module = find_rpc_module(name);

	if (module != NULL) {
		DBG_ERR("RPC module %s already loaded!\n", name);
		return NT_STATUS_OBJECT_NAME_COLLISION;
	}

	module = SMB_XMALLOC_P(struct rpc_module);
	module->name = smb_xstrdup(name);
	module->fns = fns;

	DLIST_ADD(rpc_modules, module);
	DBG_NOTICE("Successfully added RPC module '%s'\n", name);

	return NT_STATUS_OK;
}
Ejemplo n.º 21
0
/*************************************************************
 Utility function to get passwords via tty or stdin
 Used if the '-s' (smbpasswd) or '-t' (pdbedit) option is set
 to silently get passwords to enable scripting.
*************************************************************/
char *get_pass( const char *prompt, bool stdin_get)
{
	char pwd[256] = {0};
	char *p;
	int rc;

	if (stdin_get) {
		p = stdin_new_passwd();
		if (p == NULL) {
			return NULL;
		}
	} else {
		rc = samba_getpass(prompt, pwd, sizeof(pwd), false, false);
		if (rc < 0) {
			return NULL;
		}
		p = pwd;
	}
	return smb_xstrdup( p);
}
Ejemplo n.º 22
0
static int rap_share_add(struct net_context *c, int argc, const char **argv)
{
	struct cli_state *cli;
	int ret;

	struct rap_share_info_2 sinfo;
	char *p;
	char *sharename;

	if (argc == 0 || c->display_usage) {
		return net_rap_share_usage(c, argc, argv);
	}

	if (!NT_STATUS_IS_OK(net_make_ipc_connection(c, 0, &cli)))
                return -1;

	sharename = SMB_STRDUP(argv[0]);
	p = strchr(sharename, '=');
	if (p == NULL) {
		d_printf(_("Server path not specified\n"));
		SAFE_FREE(sharename);
		return net_rap_share_usage(c, argc, argv);
	}
	*p = 0;
	strlcpy((char *)sinfo.share_name, sharename, sizeof(sinfo.share_name));
	sinfo.reserved1 = '\0';
	sinfo.share_type = 0;
	sinfo.comment = c->opt_comment ? smb_xstrdup(c->opt_comment) : "";
	sinfo.perms = 0;
	sinfo.maximum_users = c->opt_maxusers;
	sinfo.active_users = 0;
	sinfo.path = p+1;
	memset(sinfo.password, '\0', sizeof(sinfo.password));
	sinfo.reserved2 = '\0';

	ret = cli_NetShareAdd(cli, &sinfo);
	cli_shutdown(cli);
	SAFE_FREE(sharename);
	return ret;
}
Ejemplo n.º 23
0
static int rap_share_add(int argc, const char **argv)
{
	struct cli_state *cli;
	int ret;
	
	RAP_SHARE_INFO_2 sinfo;
	char *p;
	char *sharename;

	if (argc == 0) {
		d_printf("\n\nShare name not specified\n");
		return net_rap_share_usage(argc, argv);
	}
			
	if (!(cli = net_make_ipc_connection(0))) 
                return -1;

	sharename = SMB_STRDUP(argv[0]);
	p = strchr(sharename, '=');
	if (p == NULL) {
		d_printf("Server path not specified\n");
		return net_rap_share_usage(argc, argv);
	}
	*p = 0;
	strlcpy(sinfo.share_name, sharename, sizeof(sinfo.share_name));
	sinfo.reserved1 = '\0';
	sinfo.share_type = 0;
	sinfo.comment = smb_xstrdup(opt_comment);
	sinfo.perms = 0;
	sinfo.maximum_users = opt_maxusers;
	sinfo.active_users = 0;
	sinfo.path = p+1;
	memset(sinfo.password, '\0', sizeof(sinfo.password));
	sinfo.reserved2 = '\0';
	
	ret = cli_NetShareAdd(cli, &sinfo);
	cli_shutdown(cli);
	return ret;
}
Ejemplo n.º 24
0
static int rap_group_add(struct net_context *c, int argc, const char **argv)
{
	struct cli_state *cli;
	int ret;
	struct rap_group_info_1 grinfo;

	if (argc == 0 || c->display_usage) {
                return net_rap_group_usage(c, argc, argv);
	}

	if (!NT_STATUS_IS_OK(net_make_ipc_connection(c, 0, &cli)))
                return -1;

	/* BB check for length 21 or smaller explicitly ? BB */
	strlcpy((char *)grinfo.group_name, argv[0], sizeof(grinfo.group_name));
	grinfo.reserved1 = '\0';
	grinfo.comment = smb_xstrdup(c->opt_comment ? c->opt_comment : "");

	ret = cli_NetGroupAdd(cli, &grinfo);
	cli_shutdown(cli);
	return ret;
}
Ejemplo n.º 25
0
static int rap_group_add(int argc, const char **argv)
{
	struct cli_state *cli;
	int ret;
	RAP_GROUP_INFO_1 grinfo;

	if (argc == 0) {
		d_printf("\n\nGroup name not specified\n");
                return net_rap_group_usage(argc, argv);
	}

	if (!(cli = net_make_ipc_connection(0)))
                return -1;
			
	/* BB check for length 21 or smaller explicitly ? BB */
	safe_strcpy(grinfo.group_name, argv[0], sizeof(grinfo.group_name)-1);
	grinfo.reserved1 = '\0';
	grinfo.comment = smb_xstrdup(opt_comment);
	
	ret = cli_NetGroupAdd(cli, &grinfo);
	cli_shutdown(cli);
	return ret;
}
Ejemplo n.º 26
0
bool fetch_ldap_pw(char **dn, char** pw)
{
	char *key = NULL;
	size_t size = 0;

	*dn = smb_xstrdup(lp_ldap_admin_dn());

	if (asprintf(&key, "%s/%s", SECRETS_LDAP_BIND_PW, *dn) < 0) {
		SAFE_FREE(*dn);
		DEBUG(0, ("fetch_ldap_pw: asprintf failed!\n"));
		return false;
	}

	*pw=(char *)secrets_fetch(key, &size);
	SAFE_FREE(key);

	if (!size) {
		/* Upgrade 2.2 style entry */
		char *p;
	        char* old_style_key = SMB_STRDUP(*dn);
		char *data;
		fstring old_style_pw;

		if (!old_style_key) {
			DEBUG(0, ("fetch_ldap_pw: strdup failed!\n"));
			return False;
		}

		for (p=old_style_key; *p; p++)
			if (*p == ',') *p = '/';

		data=(char *)secrets_fetch(old_style_key, &size);
		if ((data == NULL) || (size < sizeof(old_style_pw))) {
			DEBUG(0,("fetch_ldap_pw: neither ldap secret retrieved!\n"));
			SAFE_FREE(old_style_key);
			SAFE_FREE(*dn);
			SAFE_FREE(data);
			return False;
		}

		size = MIN(size, sizeof(fstring)-1);
		strncpy(old_style_pw, data, size);
		old_style_pw[size] = 0;

		SAFE_FREE(data);

		if (!secrets_store_ldap_pw(*dn, old_style_pw)) {
			DEBUG(0,("fetch_ldap_pw: ldap secret could not be upgraded!\n"));
			SAFE_FREE(old_style_key);
			SAFE_FREE(*dn);
			return False;
		}
		if (!secrets_delete(old_style_key)) {
			DEBUG(0,("fetch_ldap_pw: old ldap secret could not be deleted!\n"));
		}

		SAFE_FREE(old_style_key);

		*pw = smb_xstrdup(old_style_pw);
	}

	return True;
}
Ejemplo n.º 27
0
/****************************************************************************
  main program
****************************************************************************/
 int main(int argc, const char **argv)
{
	int opt,i;
	char *p;
	int rc = 0;
	int argc_new = 0;
	const char ** argv_new;
	poptContext pc;
	TALLOC_CTX *frame = talloc_stackframe();
	struct net_context *c = talloc_zero(frame, struct net_context);

	struct poptOption long_options[] = {
		{"help",	'h', POPT_ARG_NONE,   0, 'h'},
		{"workgroup",	'w', POPT_ARG_STRING, &c->opt_target_workgroup},
		{"user",	'U', POPT_ARG_STRING, &c->opt_user_name, 'U'},
		{"ipaddress",	'I', POPT_ARG_STRING, 0,'I'},
		{"port",	'p', POPT_ARG_INT,    &c->opt_port},
		{"myname",	'n', POPT_ARG_STRING, &c->opt_requester_name},
		{"server",	'S', POPT_ARG_STRING, &c->opt_host},
		{"encrypt",	'e', POPT_ARG_NONE,   NULL, 'e', N_("Encrypt SMB transport (UNIX extended servers only)") },
		{"container",	'c', POPT_ARG_STRING, &c->opt_container},
		{"comment",	'C', POPT_ARG_STRING, &c->opt_comment},
		{"maxusers",	'M', POPT_ARG_INT,    &c->opt_maxusers},
		{"flags",	'F', POPT_ARG_INT,    &c->opt_flags},
		{"long",	'l', POPT_ARG_NONE,   &c->opt_long_list_entries},
		{"reboot",	'r', POPT_ARG_NONE,   &c->opt_reboot},
		{"force",	'f', POPT_ARG_NONE,   &c->opt_force},
		{"stdin",	'i', POPT_ARG_NONE,   &c->opt_stdin},
		{"timeout",	't', POPT_ARG_INT,    &c->opt_timeout},
		{"request-timeout",0,POPT_ARG_INT,    &c->opt_request_timeout},
		{"machine-pass",'P', POPT_ARG_NONE,   &c->opt_machine_pass},
		{"kerberos",    'k', POPT_ARG_NONE,   &c->opt_kerberos},
		{"myworkgroup", 'W', POPT_ARG_STRING, &c->opt_workgroup},
		{"use-ccache",    0, POPT_ARG_NONE,   &c->opt_ccache},
		{"verbose",	'v', POPT_ARG_NONE,   &c->opt_verbose},
		{"test",	'T', POPT_ARG_NONE,   &c->opt_testmode},
		/* Options for 'net groupmap set' */
		{"local",       'L', POPT_ARG_NONE,   &c->opt_localgroup},
		{"domain",      'D', POPT_ARG_NONE,   &c->opt_domaingroup},
		{"ntname",      'N', POPT_ARG_STRING, &c->opt_newntname},
		{"rid",         'R', POPT_ARG_INT,    &c->opt_rid},
		/* Options for 'net rpc share migrate' */
		{"acls",	0, POPT_ARG_NONE,     &c->opt_acls},
		{"attrs",	0, POPT_ARG_NONE,     &c->opt_attrs},
		{"timestamps",	0, POPT_ARG_NONE,     &c->opt_timestamps},
		{"exclude",	'X', POPT_ARG_STRING, &c->opt_exclude},
		{"destination",	0, POPT_ARG_STRING,   &c->opt_destination},
		{"tallocreport", 0, POPT_ARG_NONE,    &c->do_talloc_report},
		/* Options for 'net rpc vampire (keytab)' */
		{"force-full-repl", 0, POPT_ARG_NONE, &c->opt_force_full_repl},
		{"single-obj-repl", 0, POPT_ARG_NONE, &c->opt_single_obj_repl},
		{"clean-old-entries", 0, POPT_ARG_NONE, &c->opt_clean_old_entries},
		/* Options for 'net idmap'*/
		{"db", 0, POPT_ARG_STRING, &c->opt_db},
		{"lock", 0, POPT_ARG_NONE,   &c->opt_lock},
		{"auto", 'a', POPT_ARG_NONE,   &c->opt_auto},
		{"repair", 0, POPT_ARG_NONE,   &c->opt_repair},
		/* Options for 'net registry check'*/
		{"reg-version", 0, POPT_ARG_INT, &c->opt_reg_version},
		{"output", 'o', POPT_ARG_STRING, &c->opt_output},
		{"wipe", 0, POPT_ARG_NONE, &c->opt_wipe},
		POPT_COMMON_SAMBA
		{ 0, 0, 0, 0}
	};

	zero_sockaddr(&c->opt_dest_ip);

	setup_logging(argv[0], DEBUG_STDERR);

	load_case_tables();

	setlocale(LC_ALL, "");
#if defined(HAVE_BINDTEXTDOMAIN)
	bindtextdomain(MODULE_NAME, get_dyn_LOCALEDIR());
#endif
#if defined(HAVE_TEXTDOMAIN)
	textdomain(MODULE_NAME);
#endif

	/* set default debug level to 0 regardless of what smb.conf sets */
	lp_set_cmdline("log level", "0");
	c->private_data = net_func;

	pc = poptGetContext(NULL, argc, (const char **) argv, long_options,
			    POPT_CONTEXT_KEEP_FIRST);

	while((opt = poptGetNextOpt(pc)) != -1) {
		switch (opt) {
		case 'h':
			c->display_usage = true;
			break;
		case 'e':
			c->smb_encrypt = true;
			break;
		case 'I':
			if (!interpret_string_addr(&c->opt_dest_ip,
						poptGetOptArg(pc), 0)) {
				d_fprintf(stderr, _("\nInvalid ip address specified\n"));
			} else {
				c->opt_have_ip = true;
			}
			break;
		case 'U':
			c->opt_user_specified = true;
			c->opt_user_name = SMB_STRDUP(c->opt_user_name);
			p = strchr(c->opt_user_name,'%');
			if (p) {
				*p = 0;
				c->opt_password = p+1;
			}
			break;
		default:
			d_fprintf(stderr, _("\nInvalid option %s: %s\n"),
				 poptBadOption(pc, 0), poptStrerror(opt));
			net_help(c, argc, argv);
			exit(1);
		}
	}

	lp_load_global(get_dyn_CONFIGFILE());

#if defined(HAVE_BIND_TEXTDOMAIN_CODESET)
	/* Bind our gettext results to 'unix charset'
	   
	   This ensures that the translations and any embedded strings are in the
	   same charset.  It won't be the one from the user's locale (we no
	   longer auto-detect that), but it will be self-consistent.
	*/
	bind_textdomain_codeset(MODULE_NAME, lp_unix_charset());
#endif

 	argv_new = (const char **)poptGetArgs(pc);

	argc_new = argc;
	for (i=0; i<argc; i++) {
		if (argv_new[i] == NULL) {
			argc_new = i;
			break;
		}
	}

	if (c->do_talloc_report) {
		talloc_enable_leak_report();
	}

	if (c->opt_requester_name) {
		lp_set_cmdline("netbios name", c->opt_requester_name);
	}

	if (!c->opt_user_name && getenv("LOGNAME")) {
		c->opt_user_name = getenv("LOGNAME");
	}

	if (!c->opt_workgroup) {
		c->opt_workgroup = smb_xstrdup(lp_workgroup());
	}

	if (!c->opt_target_workgroup) {
		c->opt_target_workgroup = smb_xstrdup(lp_workgroup());
	}

	if (!init_names())
		exit(1);

	load_interfaces();

	/* this makes sure that when we do things like call scripts,
	   that it won't assert because we are not root */
	sec_init();

	if (c->opt_machine_pass) {
		/* it is very useful to be able to make ads queries as the
		   machine account for testing purposes and for domain leave */

		net_use_krb_machine_account(c);
	}

	if (!c->opt_password) {
		c->opt_password = getenv("PASSWD");
	}

	/* Failing to init the msg_ctx isn't a fatal error. Only
	   root-level things (joining/leaving domains etc.) will be denied. */

	c->msg_ctx = messaging_init(c, procid_self(),
				    event_context_init(c));

	rc = net_run_function(c, argc_new-1, argv_new+1, "net", net_func);

	DEBUG(2,("return code = %d\n", rc));

	gencache_stabilize();

	libnetapi_free(c->netapi_ctx);

	poptFreeContext(pc);

	TALLOC_FREE(frame);
	return rc;
}
Ejemplo n.º 28
0
static ADS_STRUCT *ads_startup(void)
{
	ADS_STRUCT *ads;
	ADS_STATUS status;
	BOOL need_password = False;
	BOOL second_time = False;
	char *cp;
	
	/* lp_realm() should be handled by a command line param, 
	   However, the join requires that realm be set in smb.conf
	   and compares our realm with the remote server's so this is
	   ok until someone needs more flexibility */
	   
	ads = ads_init(lp_realm(), opt_target_workgroup, opt_host);

	if (!opt_user_name) {
		opt_user_name = "administrator";
	}

	if (opt_user_specified) {
		need_password = True;
	}

retry:
	if (!opt_password && need_password && !opt_machine_pass) {
		char *prompt;
		asprintf(&prompt,"%s's password: "******"name@realm", 
        * extract the realm and convert to upper case.
        * This is only used to establish the connection.
        */
       if ((cp = strchr(ads->auth.user_name, '@'))!=0) {
               *cp++ = '\0';
               ads->auth.realm = smb_xstrdup(cp);
               strupper_m(ads->auth.realm);
       }

	status = ads_connect(ads);

	if (!ADS_ERR_OK(status)) {
		if (!need_password && !second_time) {
			need_password = True;
			second_time = True;
			goto retry;
		} else {
			DEBUG(0,("ads_connect: %s\n", ads_errstr(status)));
			return NULL;
		}
	}
	return ads;
}
Ejemplo n.º 29
0
/****************************************************************************
  main program
****************************************************************************/
 int main(int argc, const char **argv)
{
	int opt,i;
	char *p;
	int rc = 0;
	int argc_new = 0;
	const char ** argv_new;
	poptContext pc;
	TALLOC_CTX *frame = talloc_stackframe();
	struct net_context *c = talloc_zero(frame, struct net_context);

	struct poptOption long_options[] = {
		{"help",	'h', POPT_ARG_NONE,   0, 'h'},
		{"workgroup",	'w', POPT_ARG_STRING, &c->opt_target_workgroup},
		{"user",	'U', POPT_ARG_STRING, &c->opt_user_name, 'U'},
		{"ipaddress",	'I', POPT_ARG_STRING, 0,'I'},
		{"port",	'p', POPT_ARG_INT,    &c->opt_port},
		{"myname",	'n', POPT_ARG_STRING, &c->opt_requester_name},
		{"server",	'S', POPT_ARG_STRING, &c->opt_host},
		{"encrypt",	'e', POPT_ARG_NONE,   NULL, 'e', "Encrypt SMB transport (UNIX extended servers only)" },
		{"container",	'c', POPT_ARG_STRING, &c->opt_container},
		{"comment",	'C', POPT_ARG_STRING, &c->opt_comment},
		{"maxusers",	'M', POPT_ARG_INT,    &c->opt_maxusers},
		{"flags",	'F', POPT_ARG_INT,    &c->opt_flags},
		{"long",	'l', POPT_ARG_NONE,   &c->opt_long_list_entries},
		{"reboot",	'r', POPT_ARG_NONE,   &c->opt_reboot},
		{"force",	'f', POPT_ARG_NONE,   &c->opt_force},
		{"stdin",	'i', POPT_ARG_NONE,   &c->opt_stdin},
		{"timeout",	't', POPT_ARG_INT,    &c->opt_timeout},
		{"request-timeout",0,POPT_ARG_INT,    &c->opt_request_timeout},
		{"machine-pass",'P', POPT_ARG_NONE,   &c->opt_machine_pass},
		{"kerberos",    'k', POPT_ARG_NONE,   &c->opt_kerberos},
		{"myworkgroup", 'W', POPT_ARG_STRING, &c->opt_workgroup},
		{"verbose",	'v', POPT_ARG_NONE,   &c->opt_verbose},
		{"test",	'T', POPT_ARG_NONE,   &c->opt_testmode},
		/* Options for 'net groupmap set' */
		{"local",       'L', POPT_ARG_NONE,   &c->opt_localgroup},
		{"domain",      'D', POPT_ARG_NONE,   &c->opt_domaingroup},
		{"ntname",      'N', POPT_ARG_STRING, &c->opt_newntname},
		{"rid",         'R', POPT_ARG_INT,    &c->opt_rid},
		/* Options for 'net rpc share migrate' */
		{"acls",	0, POPT_ARG_NONE,     &c->opt_acls},
		{"attrs",	0, POPT_ARG_NONE,     &c->opt_attrs},
		{"timestamps",	0, POPT_ARG_NONE,     &c->opt_timestamps},
		{"exclude",	'X', POPT_ARG_STRING, &c->opt_exclude},
		{"destination",	0, POPT_ARG_STRING,   &c->opt_destination},
		{"tallocreport", 0, POPT_ARG_NONE,    &c->do_talloc_report},
		/* Options for 'net rpc vampire (keytab)' */
		{"force-full-repl", 0, POPT_ARG_NONE, &c->opt_force_full_repl},
		{"single-obj-repl", 0, POPT_ARG_NONE, &c->opt_single_obj_repl},
		{"clean-old-entries", 0, POPT_ARG_NONE, &c->opt_clean_old_entries},

		POPT_COMMON_SAMBA
		{ 0, 0, 0, 0}
	};


	zero_sockaddr(&c->opt_dest_ip);

	load_case_tables();

	/* set default debug level to 0 regardless of what smb.conf sets */
	DEBUGLEVEL_CLASS[DBGC_ALL] = 0;
	dbf = x_stderr;
	c->private_data = net_func;

	pc = poptGetContext(NULL, argc, (const char **) argv, long_options,
			    POPT_CONTEXT_KEEP_FIRST);

	while((opt = poptGetNextOpt(pc)) != -1) {
		switch (opt) {
		case 'h':
			c->display_usage = true;
			break;
		case 'e':
			c->smb_encrypt = true;
			break;
		case 'I':
			if (!interpret_string_addr(&c->opt_dest_ip,
						poptGetOptArg(pc), 0)) {
				d_fprintf(stderr, "\nInvalid ip address specified\n");
			} else {
				c->opt_have_ip = true;
			}
			break;
		case 'U':
			c->opt_user_specified = true;
			c->opt_user_name = SMB_STRDUP(c->opt_user_name);
			p = strchr(c->opt_user_name,'%');
			if (p) {
				*p = 0;
				c->opt_password = p+1;
			}
			break;
		default:
			d_fprintf(stderr, "\nInvalid option %s: %s\n",
				 poptBadOption(pc, 0), poptStrerror(opt));
			net_help(c, argc, argv);
			exit(1);
		}
	}

	/*
	 * Don't load debug level from smb.conf. It should be
	 * set by cmdline arg or remain default (0)
	 */
	AllowDebugChange = false;
	lp_load(get_dyn_CONFIGFILE(), true, false, false, true);

 	argv_new = (const char **)poptGetArgs(pc);

	argc_new = argc;
	for (i=0; i<argc; i++) {
		if (argv_new[i] == NULL) {
			argc_new = i;
			break;
		}
	}

	if (c->do_talloc_report) {
		talloc_enable_leak_report();
	}

	if (c->opt_requester_name) {
		set_global_myname(c->opt_requester_name);
	}

	if (!c->opt_user_name && getenv("LOGNAME")) {
		c->opt_user_name = getenv("LOGNAME");
	}

	if (!c->opt_workgroup) {
		c->opt_workgroup = smb_xstrdup(lp_workgroup());
	}

	if (!c->opt_target_workgroup) {
		c->opt_target_workgroup = smb_xstrdup(lp_workgroup());
	}

	if (!init_names())
		exit(1);

	load_interfaces();

	/* this makes sure that when we do things like call scripts,
	   that it won't assert becouse we are not root */
	sec_init();

	if (c->opt_machine_pass) {
		/* it is very useful to be able to make ads queries as the
		   machine account for testing purposes and for domain leave */

		net_use_krb_machine_account(c);
	}

	if (!c->opt_password) {
		c->opt_password = getenv("PASSWD");
	}

	rc = net_run_function(c, argc_new-1, argv_new+1, "net", net_func);

	DEBUG(2,("return code = %d\n", rc));

	libnetapi_free(c->netapi_ctx);

	poptFreeContext(pc);

	TALLOC_FREE(frame);
	return rc;
}
Ejemplo n.º 30
0
bool cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32_t stype,
		       void (*fn)(const char *, uint32_t, const char *, void *),
		       void *state)
{
	char *rparam = NULL;
	char *rdata = NULL;
	char *rdata_end = NULL;
	unsigned int rdrcnt,rprcnt;
	char *p;
	char param[1024];
	int uLevel = 1;
	size_t len;
	uint32_t func = RAP_NetServerEnum2;
	char *last_entry = NULL;
	int total_cnt = 0;
	int return_cnt = 0;
	int res;

	errno = 0; /* reset */

	/*
	 * This may take more than one transaction, so we should loop until
	 * we no longer get a more data to process or we have all of the
	 * items.
	 */
	do {
		/* send a SMBtrans command with api NetServerEnum */
	        p = param;
		SIVAL(p,0,func); /* api number */
	        p += 2;

		if (func == RAP_NetServerEnum3) {
			strlcpy(p,"WrLehDzz", sizeof(param)-PTR_DIFF(p,param));
		} else {
			strlcpy(p,"WrLehDz", sizeof(param)-PTR_DIFF(p,param));
		}

		p = skip_string(param, sizeof(param), p);
		strlcpy(p,"B16BBDz", sizeof(param)-PTR_DIFF(p,param));

		p = skip_string(param, sizeof(param), p);
		SSVAL(p,0,uLevel);
		SSVAL(p,2,CLI_BUFFER_SIZE);
		p += 4;
		SIVAL(p,0,stype);
		p += 4;

		/* If we have more data, tell the server where
		 * to continue from.
		 */
		len = push_ascii(p,
				workgroup,
				sizeof(param) - PTR_DIFF(p,param) - 1,
				STR_TERMINATE|STR_UPPER);

		if (len == 0) {
			SAFE_FREE(last_entry);
			return false;
		}
		p += len;

		if (func == RAP_NetServerEnum3) {
			len = push_ascii(p,
					last_entry ? last_entry : "",
					sizeof(param) - PTR_DIFF(p,param) - 1,
					STR_TERMINATE);

			if (len == 0) {
				SAFE_FREE(last_entry);
				return false;
			}
			p += len;
		}

		/* Next time through we need to use the continue api */
		func = RAP_NetServerEnum3;

		if (!cli_api(cli,
			param, PTR_DIFF(p,param), 8, /* params, length, max */
			NULL, 0, CLI_BUFFER_SIZE, /* data, length, max */
		            &rparam, &rprcnt, /* return params, return size */
		            &rdata, &rdrcnt)) { /* return data, return size */

			/* break out of the loop on error */
		        res = -1;
		        break;
		}

		rdata_end = rdata + rdrcnt;
		res = rparam ? SVAL(rparam,0) : -1;

		if (res == 0 || res == ERRmoredata ||
                    (res != -1 && cli_errno(cli) == 0)) {
			char *sname = NULL;
			int i, count;
			int converter=SVAL(rparam,2);

			/* Get the number of items returned in this buffer */
			count = SVAL(rparam, 4);

			/* The next field contains the number of items left,
			 * including those returned in this buffer. So the
			 * first time through this should contain all of the
			 * entries.
			 */
			if (total_cnt == 0) {
			        total_cnt = SVAL(rparam, 6);
			}

			/* Keep track of how many we have read */
			return_cnt += count;
			p = rdata;

			/* The last name in the previous NetServerEnum reply is
			 * sent back to server in the NetServerEnum3 request
			 * (last_entry). The next reply should repeat this entry
			 * as the first element. We have no proof that this is
			 * always true, but from traces that seems to be the
			 * behavior from Window Servers. So first lets do a lot
			 * of checking, just being paranoid. If the string
			 * matches then we already saw this entry so skip it.
			 *
			 * NOTE: sv1_name field must be null terminated and has
			 * a max size of 16 (NetBIOS Name).
			 */
			if (last_entry && count && p &&
				(strncmp(last_entry, p, 16) == 0)) {
			    count -= 1; /* Skip this entry */
			    return_cnt = -1; /* Not part of total, so don't count. */
			    p = rdata + 26; /* Skip the whole record */
			}

			for (i = 0; i < count; i++, p += 26) {
				int comment_offset;
				const char *cmnt;
				const char *p1;
				char *s1, *s2;
				TALLOC_CTX *frame = talloc_stackframe();
				uint32_t entry_stype;

				if (p + 26 > rdata_end) {
					TALLOC_FREE(frame);
					break;
				}

				sname = p;
				comment_offset = (IVAL(p,22) & 0xFFFF)-converter;
				cmnt = comment_offset?(rdata+comment_offset):"";

				if (comment_offset < 0 || comment_offset >= (int)rdrcnt) {
					TALLOC_FREE(frame);
					continue;
				}

				/* Work out the comment length. */
				for (p1 = cmnt, len = 0; *p1 &&
						p1 < rdata_end; len++)
					p1++;
				if (!*p1) {
					len++;
				}

				entry_stype = IVAL(p,18) & ~SV_TYPE_LOCAL_LIST_ONLY;

				pull_string_talloc(frame,rdata,0,
					&s1,sname,16,STR_ASCII);
				pull_string_talloc(frame,rdata,0,
					&s2,cmnt,len,STR_ASCII);

				if (!s1 || !s2) {
					TALLOC_FREE(frame);
					continue;
				}

				fn(s1, entry_stype, s2, state);
				TALLOC_FREE(frame);
			}

			/* We are done with the old last entry, so now we can free it */
			if (last_entry) {
			        SAFE_FREE(last_entry); /* This will set it to null */
			}

			/* We always make a copy of  the last entry if we have one */
			if (sname) {
			        last_entry = smb_xstrdup(sname);
			}

			/* If we have more data, but no last entry then error out */
			if (!last_entry && (res == ERRmoredata)) {
			        errno = EINVAL;
			        res = 0;
			}

		}

		SAFE_FREE(rparam);
		SAFE_FREE(rdata);
	} while ((res == ERRmoredata) && (total_cnt > return_cnt));

	SAFE_FREE(rparam);
	SAFE_FREE(rdata);
	SAFE_FREE(last_entry);

	if (res == -1) {
		errno = cli_errno(cli);
	} else {
		if (!return_cnt) {
			/* this is a very special case, when the domain master for the
			   work group isn't part of the work group itself, there is something
			   wild going on */
			errno = ENOENT;
		}
	    }

	return(return_cnt > 0);
}