Example #1
0
/*
 * samr_create_user
 *
 * Create a user in the domain specified by the domain handle. If this
 * call is successful, the server will return the RID for the user and
 * a user handle, which may be used to set or query the SAM.
 *
 * Observed status codes:
 *	NT_STATUS_INVALID_PARAMETER
 *	NT_STATUS_INVALID_ACCOUNT_NAME
 *	NT_STATUS_ACCESS_DENIED
 *	NT_STATUS_USER_EXISTS
 *
 * Returns 0 on success. Otherwise returns an NT status code.
 */
DWORD
samr_create_user(mlsvc_handle_t *domain_handle, char *username,
    DWORD account_flags, DWORD *rid, mlsvc_handle_t *user_handle)
{
	struct samr_CreateUser arg;
	ndr_heap_t *heap;
	int opnum;
	int rc;
	DWORD status = 0;

	if (ndr_is_null_handle(domain_handle) ||
	    username == NULL || rid == NULL) {
		return (NT_STATUS_INVALID_PARAMETER);
	}

	opnum = SAMR_OPNUM_CreateUser;

	bzero(&arg, sizeof (struct samr_CreateUser));
	(void) memcpy(&arg.handle, &domain_handle->handle,
	    sizeof (ndr_hdid_t));

	heap = ndr_rpc_get_heap(domain_handle);
	ndr_heap_mkvcs(heap, username, (ndr_vcstr_t *)&arg.username);

	arg.account_flags = account_flags;
	arg.desired_access = 0xE00500B0;

	rc = ndr_rpc_call(domain_handle, opnum, &arg);
	if (rc != 0) {
		status = NT_STATUS_INVALID_PARAMETER;
	} else if (arg.status != 0) {
		status = NT_SC_VALUE(arg.status);

		if (status != NT_STATUS_USER_EXISTS) {
			smb_tracef("SamrCreateUser[%s]: %s", username,
			    xlate_nt_status(status));
		}
	} else {
		ndr_inherit_handle(user_handle, domain_handle);

		(void) memcpy(&user_handle->handle, &arg.user_handle,
		    sizeof (ndr_hdid_t));

		*rid = arg.rid;

		if (ndr_is_null_handle(user_handle))
			status = NT_STATUS_INVALID_HANDLE;
		else
			status = 0;
	}

	ndr_rpc_release(domain_handle);
	return (status);
}
Example #2
0
/*
 * samr_enum_local_domains
 *
 * Get the list of local domains supported by a server.
 *
 * Returns NT status codes.
 */
DWORD
samr_enum_local_domains(mlsvc_handle_t *samr_handle)
{
	struct samr_EnumLocalDomain	arg;
	int	opnum;
	DWORD	status;

	if (ndr_is_null_handle(samr_handle))
		return (NT_STATUS_INVALID_PARAMETER);

	opnum = SAMR_OPNUM_EnumLocalDomains;
	bzero(&arg, sizeof (struct samr_EnumLocalDomain));

	(void) memcpy(&arg.handle, &samr_handle->handle,
	    sizeof (samr_handle_t));
	arg.enum_context = 0;
	arg.max_length = 0x00002000;	/* Value used by NT */

	if (ndr_rpc_call(samr_handle, opnum, &arg) != 0) {
		status = NT_STATUS_INVALID_PARAMETER;
	} else {
		status = NT_SC_VALUE(arg.status);

		/*
		 * Handle none-mapped status quietly.
		 */
		if (status != NT_STATUS_NONE_MAPPED)
			ndr_rpc_status(samr_handle, opnum, arg.status);
	}

	ndr_rpc_release(samr_handle);
	return (status);
}
Example #3
0
/*ARGSUSED*/
static DWORD
samr_connect1(char *server, char *domain, char *username, DWORD access_mask,
    mlsvc_handle_t *samr_handle)
{
	struct samr_Connect arg;
	int opnum;
	DWORD status;

	bzero(&arg, sizeof (struct samr_Connect));
	opnum = SAMR_OPNUM_Connect;
	status = NT_STATUS_SUCCESS;

	arg.servername = ndr_rpc_malloc(samr_handle, sizeof (DWORD));
	*(arg.servername) = 0x0001005c;
	arg.access_mask = access_mask;

	if (ndr_rpc_call(samr_handle, opnum, &arg) != 0) {
		status = NT_STATUS_UNSUCCESSFUL;
	} else if (arg.status != 0) {
		status = NT_SC_VALUE(arg.status);
	} else {
		(void) memcpy(&samr_handle->handle, &arg.handle,
		    sizeof (ndr_hdid_t));

		if (ndr_is_null_handle(samr_handle))
			status = NT_STATUS_INVALID_HANDLE;
	}

	ndr_rpc_release(samr_handle);
	return (status);
}
Example #4
0
/*
 * samr_lookup_domain
 *
 * Lookup up the domain SID for the specified domain name. The handle
 * should be one returned from samr_connect. The allocated memory for
 * the returned SID must be freed by caller.
 */
smb_sid_t *
samr_lookup_domain(mlsvc_handle_t *samr_handle, char *domain_name)
{
	struct samr_LookupDomain	arg;
	smb_sid_t	*domsid = NULL;
	int		opnum;
	size_t		length;

	if (ndr_is_null_handle(samr_handle) || domain_name == NULL)
		return (NULL);

	opnum = SAMR_OPNUM_LookupDomain;
	bzero(&arg, sizeof (struct samr_LookupDomain));

	(void) memcpy(&arg.handle, &samr_handle->handle,
	    sizeof (samr_handle_t));

	length = smb_wcequiv_strlen(domain_name);
	if (ndr_rpc_server_os(samr_handle) == NATIVE_OS_WIN2000)
		length += sizeof (smb_wchar_t);

	arg.domain_name.length = length;
	arg.domain_name.allosize = length;
	arg.domain_name.str = (unsigned char *)domain_name;

	if (ndr_rpc_call(samr_handle, opnum, &arg) == 0)
		domsid = smb_sid_dup((smb_sid_t *)arg.sid);

	ndr_rpc_release(samr_handle);
	return (domsid);
}
Example #5
0
/*
 * samr_get_user_pwinfo
 *
 * Get some user password info. I'm not sure what this is yet but it is
 * part of the create user sequence. The handle must be a valid user
 * handle. Since I don't know what this is returning, I haven't provided
 * any return data yet.
 *
 * Returns 0 on success. Otherwise returns an NT status code.
 */
DWORD
samr_get_user_pwinfo(mlsvc_handle_t *user_handle)
{
	struct samr_GetUserPwInfo arg;
	int	opnum;
	DWORD	status;

	if (ndr_is_null_handle(user_handle))
		return (NT_STATUS_INVALID_PARAMETER);

	opnum = SAMR_OPNUM_GetUserPwInfo;
	bzero(&arg, sizeof (struct samr_GetUserPwInfo));
	(void) memcpy(&arg.user_handle, &user_handle->handle,
	    sizeof (samr_handle_t));

	if (ndr_rpc_call(user_handle, opnum, &arg) != 0) {
		status = NT_STATUS_INVALID_PARAMETER;
	} else if (arg.status != 0) {
		ndr_rpc_status(user_handle, opnum, arg.status);
		status = NT_SC_VALUE(arg.status);
	} else {
		status = 0;
	}

	ndr_rpc_release(user_handle);
	return (status);
}
Example #6
0
/*
 * samr_query_user_info
 *
 * Query information on a specific user. The handle must be a valid
 * user handle obtained via samr_open_user.
 *
 * Returns 0 on success, otherwise returns -ve error code.
 */
int
samr_query_user_info(mlsvc_handle_t *user_handle, WORD switch_value,
    union samr_user_info *user_info)
{
	struct samr_QueryUserInfo	arg;
	int	opnum;
	int	rc;

	if (ndr_is_null_handle(user_handle) || user_info == 0)
		return (-1);

	opnum = SAMR_OPNUM_QueryUserInfo;
	bzero(&arg, sizeof (struct samr_QueryUserInfo));

	(void) memcpy(&arg.user_handle, &user_handle->handle,
	    sizeof (samr_handle_t));
	arg.switch_value = switch_value;

	if (ndr_rpc_call(user_handle, opnum, &arg) != 0) {
		ndr_rpc_release(user_handle);
		return (-1);
	}

	if (arg.status != 0)
		rc = -1;
	else
		rc = samr_setup_user_info(switch_value, &arg, user_info);

	ndr_rpc_release(user_handle);
	return (rc);
}
Example #7
0
/*ARGSUSED*/
static DWORD
samr_connect4(char *server, char *domain, char *username, DWORD access_mask,
    mlsvc_handle_t *samr_handle)
{
	struct samr_Connect4 arg;
	int opnum;
	DWORD status;
	int len;

	bzero(&arg, sizeof (struct samr_Connect4));
	opnum = SAMR_OPNUM_Connect4;
	status = NT_STATUS_SUCCESS;

	len = strlen(server) + 4;
	arg.servername = ndr_rpc_malloc(samr_handle, len);
	(void) snprintf((char *)arg.servername, len, "\\\\%s", server);
	arg.revision = SAMR_REVISION_2;
	arg.access_mask = access_mask;

	if (ndr_rpc_call(samr_handle, opnum, &arg) != 0) {
		status = NT_STATUS_UNSUCCESSFUL;
	} else if (arg.status != 0) {
		status = NT_SC_VALUE(arg.status);
	} else {
		(void) memcpy(&samr_handle->handle, &arg.handle,
		    sizeof (ndr_hdid_t));

		if (ndr_is_null_handle(samr_handle))
			status = NT_STATUS_INVALID_HANDLE;
	}

	ndr_rpc_release(samr_handle);
	return (status);
}
Example #8
0
/*
 * lsar_open_account
 *
 * Obtain an LSA account handle. The lsa_handle must be a valid handle
 * obtained via lsar_open_policy2. The main thing to remember here is
 * to set up the context in the lsa_account_handle. I'm not sure what
 * the requirements are for desired access. Some values require admin
 * access.
 *
 * Returns 0 on success. Otherwise non-zero to indicate a failure.
 */
int
lsar_open_account(mlsvc_handle_t *lsa_handle, struct mslsa_sid *sid,
    mlsvc_handle_t *lsa_account_handle)
{
	struct mslsa_OpenAccount arg;
	int opnum;
	int rc;

	if (ndr_is_null_handle(lsa_handle) || sid == NULL)
		return (-1);

	opnum = LSARPC_OPNUM_OpenAccount;
	bzero(&arg, sizeof (struct mslsa_OpenAccount));

	(void) memcpy(&arg.handle, lsa_handle, sizeof (mslsa_handle_t));
	arg.sid = sid;
	arg.access_mask = STANDARD_RIGHTS_REQUIRED
#if 0
	    | POLICY_VIEW_AUDIT_INFORMATION
	    | POLICY_GET_PRIVATE_INFORMATION
	    | POLICY_TRUST_ADMIN
#endif
	    | POLICY_VIEW_LOCAL_INFORMATION;

	if ((rc = ndr_rpc_call(lsa_handle, opnum, &arg)) != 0)
		return (-1);

	if (arg.status != 0) {
		rc = -1;
	} else {
		ndr_inherit_handle(lsa_account_handle, lsa_handle);

		(void) memcpy(&lsa_account_handle->handle,
		    &arg.account_handle, sizeof (ndr_hdid_t));

		if (ndr_is_null_handle(lsa_account_handle))
			rc = -1;
	}

	ndr_rpc_release(lsa_handle);
	return (rc);
}
Example #9
0
/*
 * samr_open_domain
 *
 * We use a SAM handle to obtain a handle for a domain, specified by
 * the SID. The SID can be obtain via the LSA interface. A handle for
 * the domain is returned in domain_handle.
 */
DWORD
samr_open_domain(mlsvc_handle_t *samr_handle, DWORD access_mask,
    struct samr_sid *sid, mlsvc_handle_t *domain_handle)
{
	struct samr_OpenDomain arg;
	int opnum;
	DWORD status;

	if (ndr_is_null_handle(samr_handle) ||
	    sid == NULL || domain_handle == NULL) {
		return (NT_STATUS_INVALID_PARAMETER);
	}

	opnum = SAMR_OPNUM_OpenDomain;
	bzero(&arg, sizeof (struct samr_OpenDomain));
	(void) memcpy(&arg.handle, &samr_handle->handle, sizeof (ndr_hdid_t));

	arg.access_mask = access_mask;
	arg.sid = sid;

	if (ndr_rpc_call(samr_handle, opnum, &arg) != 0) {
		status = NT_STATUS_UNSUCCESSFUL;
	} else if (arg.status != 0) {
		status = arg.status;
	} else {
		status = NT_STATUS_SUCCESS;
		ndr_inherit_handle(domain_handle, samr_handle);

		(void) memcpy(&domain_handle->handle, &arg.domain_handle,
		    sizeof (ndr_hdid_t));

		if (ndr_is_null_handle(domain_handle))
			status = NT_STATUS_INVALID_HANDLE;
	}

	if (status != NT_STATUS_SUCCESS)
		ndr_rpc_status(samr_handle, opnum, status);

	ndr_rpc_release(samr_handle);
	return (status);
}
Example #10
0
/*
 * samr_lookup_domain_names
 *
 * Lookup up the given name in the domain specified by domain_handle.
 * Upon a successful lookup the information is returned in the account
 * arg and caller must free allocated memories by calling smb_account_free().
 *
 * Returns NT status codes.
 */
uint32_t
samr_lookup_domain_names(mlsvc_handle_t *domain_handle, char *name,
    smb_account_t *account)
{
	struct samr_LookupNames	arg;
	int			opnum;
	uint32_t		status;
	size_t			length;

	if (ndr_is_null_handle(domain_handle) ||
	    name == NULL || account == NULL) {
		return (NT_STATUS_INVALID_PARAMETER);
	}

	bzero(account, sizeof (smb_account_t));
	opnum = SAMR_OPNUM_LookupNames;
	bzero(&arg, sizeof (struct samr_LookupNames));

	(void) memcpy(&arg.handle, &domain_handle->handle,
	    sizeof (samr_handle_t));
	arg.n_entry = 1;
	arg.max_n_entry = 1000;
	arg.index = 0;
	arg.total = 1;

	length = smb_wcequiv_strlen(name);
	if (ndr_rpc_server_os(domain_handle) == NATIVE_OS_WIN2000)
		length += sizeof (smb_wchar_t);

	arg.name.length = length;
	arg.name.allosize = length;
	arg.name.str = (unsigned char *)name;

	if (ndr_rpc_call(domain_handle, opnum, &arg) != 0) {
		status = NT_STATUS_INVALID_PARAMETER;
	} else if (arg.status != NT_STATUS_SUCCESS) {
		status = NT_SC_VALUE(arg.status);

		/*
		 * Handle none-mapped status quietly.
		 */
		if (status != NT_STATUS_NONE_MAPPED)
			ndr_rpc_status(domain_handle, opnum, arg.status);
	} else {
		account->a_type = arg.rid_types.rid_type[0];
		account->a_rid = arg.rids.rid[0];
		status = NT_STATUS_SUCCESS;
	}

	ndr_rpc_release(domain_handle);
	return (status);
}
Example #11
0
/*
 * samr_open_group
 *
 * Use a domain handle to obtain a handle for a group, specified by the
 * group RID. A group RID (effectively a gid) can be obtained via the
 * LSA interface. A handle for the group is returned in group_handle.
 * Once you have a group handle it should be possible to query the SAM
 * for information on that group.
 */
int
samr_open_group(
	mlsvc_handle_t *domain_handle,
	DWORD rid,
	mlsvc_handle_t *group_handle)
{
	struct samr_OpenGroup arg;
	int opnum;
	int rc;

	if (ndr_is_null_handle(domain_handle) || group_handle == NULL)
		return (-1);

	opnum = SAMR_OPNUM_OpenGroup;
	bzero(&arg, sizeof (struct samr_OpenUser));
	(void) memcpy(&arg.handle, &domain_handle->handle,
	    sizeof (ndr_hdid_t));
	arg.access_mask = SAM_LOOKUP_INFORMATION | SAM_ACCESS_USER_READ;
	arg.rid = rid;

	if ((rc = ndr_rpc_call(domain_handle, opnum, &arg)) != 0)
		return (-1);

	if (arg.status != 0) {
		ndr_rpc_status(domain_handle, opnum, arg.status);
		rc = -1;
	} else {
		ndr_inherit_handle(group_handle, domain_handle);

		(void) memcpy(&group_handle->handle, &arg.group_handle,
		    sizeof (ndr_hdid_t));

		if (ndr_is_null_handle(group_handle))
			rc = -1;
	}

	ndr_rpc_release(domain_handle);
	return (rc);
}
Example #12
0
/*
 * samr_open_user
 *
 * Use a domain handle to obtain a handle for a user, specified by the
 * user RID. A user RID (effectively a uid) can be obtained via the
 * LSA interface. A handle for the user is returned in user_handle.
 * Once you have a user handle it should be possible to query the SAM
 * for information on that user.
 */
DWORD
samr_open_user(mlsvc_handle_t *domain_handle, DWORD access_mask, DWORD rid,
    mlsvc_handle_t *user_handle)
{
	struct samr_OpenUser arg;
	int opnum;
	DWORD status = NT_STATUS_SUCCESS;

	if (ndr_is_null_handle(domain_handle) || user_handle == NULL)
		return (NT_STATUS_INVALID_PARAMETER);

	opnum = SAMR_OPNUM_OpenUser;
	bzero(&arg, sizeof (struct samr_OpenUser));
	(void) memcpy(&arg.handle, &domain_handle->handle,
	    sizeof (ndr_hdid_t));
	arg.access_mask = access_mask;
	arg.rid = rid;

	if (ndr_rpc_call(domain_handle, opnum, &arg) != 0) {
		status = NT_STATUS_UNSUCCESSFUL;
	} else if (arg.status != 0) {
		ndr_rpc_status(domain_handle, opnum, arg.status);
		status = NT_SC_VALUE(arg.status);
	} else {
		ndr_inherit_handle(user_handle, domain_handle);

		(void) memcpy(&user_handle->handle, &arg.user_handle,
		    sizeof (ndr_hdid_t));

		if (ndr_is_null_handle(user_handle))
			status = NT_STATUS_INVALID_HANDLE;
	}

	ndr_rpc_release(domain_handle);
	return (status);
}
Example #13
0
/*
 * lsar_open_policy2
 *
 * Obtain an LSA policy handle. A policy handle is required to access
 * LSA resources on a remote server. The server name supplied here does
 * not need the double backslash prefix; it is added here. Call this
 * function via lsar_open to ensure that the appropriate connection is
 * in place.
 *
 * Returns 0 on success. Otherwise non-zero to indicate a failure.
 */
int
lsar_open_policy2(char *server, char *domain, char *username,
    mlsvc_handle_t *lsa_handle)
{
	struct mslsa_OpenPolicy2 arg;
	int opnum;
	int len;
	int rc;

	rc = ndr_rpc_bind(lsa_handle, server, domain, username, "LSARPC");
	if (rc != 0)
		return (-1);

	opnum = LSARPC_OPNUM_OpenPolicy2;
	bzero(&arg, sizeof (struct mslsa_OpenPolicy2));

	len = strlen(server) + 4;
	arg.servername = ndr_rpc_malloc(lsa_handle, len);
	if (arg.servername == NULL) {
		ndr_rpc_unbind(lsa_handle);
		return (-1);
	}

	(void) snprintf((char *)arg.servername, len, "\\\\%s", server);
	arg.attributes.length = sizeof (struct mslsa_object_attributes);
	arg.desiredAccess = MAXIMUM_ALLOWED;

	if ((rc = ndr_rpc_call(lsa_handle, opnum, &arg)) != 0) {
		ndr_rpc_unbind(lsa_handle);
		return (-1);
	}

	if (arg.status != 0) {
		rc = -1;
	} else {
		(void) memcpy(&lsa_handle->handle, &arg.domain_handle,
		    sizeof (ndr_hdid_t));

		if (ndr_is_null_handle(lsa_handle))
			rc = -1;
	}

	ndr_rpc_release(lsa_handle);

	if (rc != 0)
		ndr_rpc_unbind(lsa_handle);
	return (rc);
}
Example #14
0
/*ARGSUSED*/
static DWORD
samr_connect5(char *server, char *domain, char *username, DWORD access_mask,
    mlsvc_handle_t *samr_handle)
{
	struct samr_Connect5 arg;
	int len;
	int opnum;
	DWORD status;
	smb_domainex_t dinfo;

	bzero(&arg, sizeof (struct samr_Connect5));
	opnum = SAMR_OPNUM_Connect5;
	status = NT_STATUS_SUCCESS;

	if (!smb_domain_getinfo(&dinfo))
		return (NT_STATUS_CANT_ACCESS_DOMAIN_INFO);

	len = strlen(server) + strlen(dinfo.d_primary.di_fqname) + 4;
	arg.servername = ndr_rpc_malloc(samr_handle, len);

	if (*dinfo.d_primary.di_fqname != '\0')
		(void) snprintf((char *)arg.servername, len, "\\\\%s.%s",
		    server, dinfo.d_primary.di_fqname);
	else
		(void) snprintf((char *)arg.servername, len, "\\\\%s", server);

	arg.access_mask = SAM_ENUM_LOCAL_DOMAIN;
	arg.unknown2_00000001 = 0x00000001;
	arg.unknown3_00000001 = 0x00000001;
	arg.unknown4_00000003 = 0x00000003;
	arg.unknown5_00000000 = 0x00000000;

	if (ndr_rpc_call(samr_handle, opnum, &arg) != 0) {
		status = NT_STATUS_UNSUCCESSFUL;
	} else if (arg.status != 0) {
		status = NT_SC_VALUE(arg.status);
	} else {

		(void) memcpy(&samr_handle->handle, &arg.handle,
		    sizeof (ndr_hdid_t));

		if (ndr_is_null_handle(samr_handle))
			status = NT_STATUS_INVALID_HANDLE;
	}

	ndr_rpc_release(samr_handle);
	return (status);
}
Example #15
0
/*
 * lsar_close
 *
 * Close the LSA connection associated with the handle. The lsa_handle
 * must be a valid handle obtained via a call to lsar_open_policy2 or
 * lsar_open_account. On success the handle will be zeroed out to
 * ensure that it is not used again. If this is the top level handle
 * (i.e. the one obtained via lsar_open_policy2) the pipe is closed.
 *
 * Returns 0 on success. Otherwise non-zero to indicate a failure.
 */
int
lsar_close(mlsvc_handle_t *lsa_handle)
{
	struct mslsa_CloseHandle arg;
	int opnum;

	if (ndr_is_null_handle(lsa_handle))
		return (-1);

	opnum = LSARPC_OPNUM_CloseHandle;
	bzero(&arg, sizeof (struct mslsa_CloseHandle));
	(void) memcpy(&arg.handle, lsa_handle, sizeof (mslsa_handle_t));

	(void) ndr_rpc_call(lsa_handle, opnum, &arg);
	ndr_rpc_release(lsa_handle);

	if (ndr_is_bind_handle(lsa_handle))
		ndr_rpc_unbind(lsa_handle);

	bzero(lsa_handle, sizeof (mlsvc_handle_t));
	return (0);
}
Example #16
0
/*
 * samr_query_user_groups
 *
 * Query the groups for a specific user. The handle must be a valid
 * user handle obtained via samr_open_user. The list of groups is
 * returned in group_info. Note that group_info->groups is allocated
 * using malloc. The caller is responsible for deallocating this
 * memory when it is no longer required. If group_info->n_entry is 0
 * then no memory was allocated.
 *
 * Returns 0 on success, otherwise returns -1.
 */
int
samr_query_user_groups(mlsvc_handle_t *user_handle, int *n_groups,
    struct samr_UserGroups **groups)
{
	struct samr_QueryUserGroups arg;
	int	opnum;
	int	rc;
	int	nbytes;

	if (ndr_is_null_handle(user_handle))
		return (-1);

	opnum = SAMR_OPNUM_QueryUserGroups;
	bzero(&arg, sizeof (struct samr_QueryUserGroups));

	(void) memcpy(&arg.user_handle, &user_handle->handle,
	    sizeof (samr_handle_t));

	rc = ndr_rpc_call(user_handle, opnum, &arg);
	if (rc == 0) {
		if (arg.info == 0) {
			rc = -1;
		} else {
			nbytes = arg.info->n_entry *
			    sizeof (struct samr_UserGroups);

			if ((*groups = malloc(nbytes)) == NULL) {
				*n_groups = 0;
				rc = -1;
			} else {
				*n_groups = arg.info->n_entry;
				bcopy(arg.info->groups, *groups, nbytes);
			}
		}
	}

	ndr_rpc_release(user_handle);
	return (rc);
}
Example #17
0
/*
 * samr_close_handle
 *
 * This is function closes any valid handle, i.e. sam, domain, user etc.
 * If the handle being closed is the top level connect handle, we unbind.
 * Then we zero out the handle to invalidate it.
 */
int
samr_close_handle(mlsvc_handle_t *samr_handle)
{
	struct samr_CloseHandle arg;
	int opnum;

	if (ndr_is_null_handle(samr_handle))
		return (-1);

	opnum = SAMR_OPNUM_CloseHandle;
	bzero(&arg, sizeof (struct samr_CloseHandle));
	(void) memcpy(&arg.handle, &samr_handle->handle, sizeof (ndr_hdid_t));

	(void) ndr_rpc_call(samr_handle, opnum, &arg);
	ndr_rpc_release(samr_handle);

	if (ndr_is_bind_handle(samr_handle))
		ndr_rpc_unbind(samr_handle);

	bzero(samr_handle, sizeof (mlsvc_handle_t));
	return (0);
}
Example #18
0
/*ARGSUSED*/
DWORD
samr_set_user_info(mlsvc_handle_t *user_handle)
{
	unsigned char ssn_key[SMBAUTH_SESSION_KEY_SZ];
	struct samr_SetUserInfo arg;
	int opnum;
	DWORD status = 0;

	if (ndr_is_null_handle(user_handle))
		return (NT_STATUS_INVALID_PARAMETER);

	if (ndr_rpc_get_ssnkey(user_handle, ssn_key, sizeof (ssn_key)))
		return (NT_STATUS_INVALID_PARAMETER);

	opnum = SAMR_OPNUM_SetUserInfo;
	bzero(&arg, sizeof (struct samr_SetUserInfo));
	(void) memcpy(&arg.user_handle, &user_handle->handle,
	    sizeof (samr_handle_t));

	arg.info.index = SAMR_SET_USER_INFO_23;
	arg.info.switch_value = SAMR_SET_USER_INFO_23;

	samr_set_user_unknowns(&arg.info.ru.info23);
	samr_set_user_logon_hours(&arg);

	if (samr_set_user_password(ssn_key, arg.info.ru.info23.password) < 0)
		status = NT_STATUS_INTERNAL_ERROR;

	if (ndr_rpc_call(user_handle, opnum, &arg) != 0) {
		status = NT_STATUS_INVALID_PARAMETER;
	} else if (arg.status != 0) {
		ndr_rpc_status(user_handle, opnum, arg.status);
		status = NT_SC_VALUE(arg.status);
	}

	ndr_rpc_release(user_handle);
	return (status);
}