111337SWilliam.Krier@Sun.COM /*
211337SWilliam.Krier@Sun.COM * CDDL HEADER START
311337SWilliam.Krier@Sun.COM *
411337SWilliam.Krier@Sun.COM * The contents of this file are subject to the terms of the
511337SWilliam.Krier@Sun.COM * Common Development and Distribution License (the "License").
611337SWilliam.Krier@Sun.COM * You may not use this file except in compliance with the License.
711337SWilliam.Krier@Sun.COM *
811337SWilliam.Krier@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
911337SWilliam.Krier@Sun.COM * or http://www.opensolaris.org/os/licensing.
1011337SWilliam.Krier@Sun.COM * See the License for the specific language governing permissions
1111337SWilliam.Krier@Sun.COM * and limitations under the License.
1211337SWilliam.Krier@Sun.COM *
1311337SWilliam.Krier@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each
1411337SWilliam.Krier@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1511337SWilliam.Krier@Sun.COM * If applicable, add the following below this CDDL HEADER, with the
1611337SWilliam.Krier@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying
1711337SWilliam.Krier@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner]
1811337SWilliam.Krier@Sun.COM *
1911337SWilliam.Krier@Sun.COM * CDDL HEADER END
2011337SWilliam.Krier@Sun.COM */
21*12508Samw@Sun.COM
2211337SWilliam.Krier@Sun.COM /*
23*12508Samw@Sun.COM * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
2411337SWilliam.Krier@Sun.COM */
2511337SWilliam.Krier@Sun.COM
2611337SWilliam.Krier@Sun.COM /*
2711337SWilliam.Krier@Sun.COM * Local Security Authority RPC (LSAR) client-side interface.
2811337SWilliam.Krier@Sun.COM */
2911337SWilliam.Krier@Sun.COM
3011337SWilliam.Krier@Sun.COM #include <sys/errno.h>
3111337SWilliam.Krier@Sun.COM #include <stdio.h>
3211337SWilliam.Krier@Sun.COM #include <stdlib.h>
3311337SWilliam.Krier@Sun.COM #include <strings.h>
3411337SWilliam.Krier@Sun.COM
3511337SWilliam.Krier@Sun.COM #include <smbsrv/libsmb.h>
3611337SWilliam.Krier@Sun.COM #include <smbsrv/libmlsvc.h>
3711337SWilliam.Krier@Sun.COM #include <smbsrv/smbinfo.h>
3811337SWilliam.Krier@Sun.COM #include <smbsrv/ntaccess.h>
3911337SWilliam.Krier@Sun.COM #include <smbsrv/ntlocale.h>
4011337SWilliam.Krier@Sun.COM #include <smbsrv/string.h>
4111337SWilliam.Krier@Sun.COM #include <lsalib.h>
4211337SWilliam.Krier@Sun.COM
4311337SWilliam.Krier@Sun.COM /*
4411337SWilliam.Krier@Sun.COM * The maximum number of bytes we are prepared to deal with in a
4511337SWilliam.Krier@Sun.COM * response.
4611337SWilliam.Krier@Sun.COM */
4711337SWilliam.Krier@Sun.COM #define MLSVC_MAX_RESPONSE_LEN 1024
4811337SWilliam.Krier@Sun.COM
4911337SWilliam.Krier@Sun.COM /*
5011337SWilliam.Krier@Sun.COM * This structure is used when looking up names. We only lookup one
5111337SWilliam.Krier@Sun.COM * name at a time but the structure will allow for more.
5211337SWilliam.Krier@Sun.COM */
5311337SWilliam.Krier@Sun.COM typedef struct lsa_names {
5411337SWilliam.Krier@Sun.COM uint32_t n_entry;
5511337SWilliam.Krier@Sun.COM mslsa_string_t name[8];
5611337SWilliam.Krier@Sun.COM } lsa_names_t;
5711337SWilliam.Krier@Sun.COM
5811337SWilliam.Krier@Sun.COM typedef DWORD (*lsar_nameop_t)(mlsvc_handle_t *, lsa_names_t *,
5911337SWilliam.Krier@Sun.COM smb_account_t *);
6011337SWilliam.Krier@Sun.COM
6111337SWilliam.Krier@Sun.COM static uint32_t lsar_lookup_names1(mlsvc_handle_t *, lsa_names_t *,
6211337SWilliam.Krier@Sun.COM smb_account_t *);
6311337SWilliam.Krier@Sun.COM static uint32_t lsar_lookup_names2(mlsvc_handle_t *, lsa_names_t *,
6411337SWilliam.Krier@Sun.COM smb_account_t *);
6511337SWilliam.Krier@Sun.COM static uint32_t lsar_lookup_names3(mlsvc_handle_t *, lsa_names_t *,
6611337SWilliam.Krier@Sun.COM smb_account_t *);
6711337SWilliam.Krier@Sun.COM static uint32_t lsar_lookup_sids1(mlsvc_handle_t *, lsa_sid_t *,
6811337SWilliam.Krier@Sun.COM smb_account_t *);
6911337SWilliam.Krier@Sun.COM static uint32_t lsar_lookup_sids2(mlsvc_handle_t *, lsa_sid_t *,
7011337SWilliam.Krier@Sun.COM smb_account_t *account);
7111337SWilliam.Krier@Sun.COM
7211337SWilliam.Krier@Sun.COM static char *lsar_get_username(const char *);
7311337SWilliam.Krier@Sun.COM static void smb_account_trace(const smb_account_t *);
7411337SWilliam.Krier@Sun.COM
7511337SWilliam.Krier@Sun.COM static void lsar_set_trusted_domains_ex(struct mslsa_EnumTrustedDomainBufEx *,
7611337SWilliam.Krier@Sun.COM smb_trusted_domains_t *);
7711337SWilliam.Krier@Sun.COM static void lsar_set_trusted_domains(struct mslsa_EnumTrustedDomainBuf *,
7811337SWilliam.Krier@Sun.COM smb_trusted_domains_t *);
7911337SWilliam.Krier@Sun.COM
8011337SWilliam.Krier@Sun.COM /*
8111337SWilliam.Krier@Sun.COM * lsar_open
8211337SWilliam.Krier@Sun.COM *
8311337SWilliam.Krier@Sun.COM * This is a wrapper round lsar_open_policy2 to ensure that we connect
8411337SWilliam.Krier@Sun.COM * using the appropriate domain information.
8511337SWilliam.Krier@Sun.COM *
8611337SWilliam.Krier@Sun.COM * If username argument is NULL, an anonymous connection will be established.
8711337SWilliam.Krier@Sun.COM * Otherwise, an authenticated connection will be established.
8811337SWilliam.Krier@Sun.COM *
8911337SWilliam.Krier@Sun.COM * On success 0 is returned. Otherwise a -ve error code.
9011337SWilliam.Krier@Sun.COM */
lsar_open(char * server,char * domain,char * username,mlsvc_handle_t * domain_handle)9111337SWilliam.Krier@Sun.COM int lsar_open(char *server, char *domain, char *username,
9211337SWilliam.Krier@Sun.COM mlsvc_handle_t *domain_handle)
9311337SWilliam.Krier@Sun.COM {
9411337SWilliam.Krier@Sun.COM if (server == NULL || domain == NULL)
9511337SWilliam.Krier@Sun.COM return (-1);
9611337SWilliam.Krier@Sun.COM
9711337SWilliam.Krier@Sun.COM if (username == NULL)
9811337SWilliam.Krier@Sun.COM username = MLSVC_ANON_USER;
9911337SWilliam.Krier@Sun.COM
10011337SWilliam.Krier@Sun.COM return (lsar_open_policy2(server, domain, username, domain_handle));
10111337SWilliam.Krier@Sun.COM }
10211337SWilliam.Krier@Sun.COM
10311337SWilliam.Krier@Sun.COM /*
10411337SWilliam.Krier@Sun.COM * lsar_open_policy2
10511337SWilliam.Krier@Sun.COM *
10611337SWilliam.Krier@Sun.COM * Obtain an LSA policy handle. A policy handle is required to access
10711337SWilliam.Krier@Sun.COM * LSA resources on a remote server. The server name supplied here does
10811337SWilliam.Krier@Sun.COM * not need the double backslash prefix; it is added here. Call this
10911337SWilliam.Krier@Sun.COM * function via lsar_open to ensure that the appropriate connection is
11011337SWilliam.Krier@Sun.COM * in place.
11111337SWilliam.Krier@Sun.COM *
11211337SWilliam.Krier@Sun.COM * I'm not sure if it makes a difference whether we use GENERIC_EXECUTE
11311337SWilliam.Krier@Sun.COM * or STANDARD_RIGHTS_EXECUTE. For a long time I used the standard bit
11411337SWilliam.Krier@Sun.COM * and then I added the generic bit while working on privileges because
11511337SWilliam.Krier@Sun.COM * NT sets that bit. I don't think it matters.
11611337SWilliam.Krier@Sun.COM *
11711337SWilliam.Krier@Sun.COM * Returns 0 on success. Otherwise non-zero to indicate a failure.
11811337SWilliam.Krier@Sun.COM */
11911337SWilliam.Krier@Sun.COM int
lsar_open_policy2(char * server,char * domain,char * username,mlsvc_handle_t * lsa_handle)12011337SWilliam.Krier@Sun.COM lsar_open_policy2(char *server, char *domain, char *username,
12111337SWilliam.Krier@Sun.COM mlsvc_handle_t *lsa_handle)
12211337SWilliam.Krier@Sun.COM {
12311337SWilliam.Krier@Sun.COM struct mslsa_OpenPolicy2 arg;
12411337SWilliam.Krier@Sun.COM int opnum;
12511337SWilliam.Krier@Sun.COM int len;
12611337SWilliam.Krier@Sun.COM int rc;
12711337SWilliam.Krier@Sun.COM
12811337SWilliam.Krier@Sun.COM rc = ndr_rpc_bind(lsa_handle, server, domain, username, "LSARPC");
12911337SWilliam.Krier@Sun.COM if (rc != 0)
13011337SWilliam.Krier@Sun.COM return (-1);
13111337SWilliam.Krier@Sun.COM
13211337SWilliam.Krier@Sun.COM opnum = LSARPC_OPNUM_OpenPolicy2;
13311337SWilliam.Krier@Sun.COM bzero(&arg, sizeof (struct mslsa_OpenPolicy2));
13411337SWilliam.Krier@Sun.COM
13511337SWilliam.Krier@Sun.COM len = strlen(server) + 4;
13611337SWilliam.Krier@Sun.COM arg.servername = ndr_rpc_malloc(lsa_handle, len);
13711337SWilliam.Krier@Sun.COM if (arg.servername == NULL) {
13811337SWilliam.Krier@Sun.COM ndr_rpc_unbind(lsa_handle);
13911337SWilliam.Krier@Sun.COM return (-1);
14011337SWilliam.Krier@Sun.COM }
14111337SWilliam.Krier@Sun.COM
14211337SWilliam.Krier@Sun.COM (void) snprintf((char *)arg.servername, len, "\\\\%s", server);
14311337SWilliam.Krier@Sun.COM arg.attributes.length = sizeof (struct mslsa_object_attributes);
14411337SWilliam.Krier@Sun.COM
14511337SWilliam.Krier@Sun.COM if (ndr_rpc_server_os(lsa_handle) == NATIVE_OS_WIN2000) {
14611337SWilliam.Krier@Sun.COM arg.desiredAccess = MAXIMUM_ALLOWED;
14711337SWilliam.Krier@Sun.COM } else {
14811337SWilliam.Krier@Sun.COM arg.desiredAccess = GENERIC_EXECUTE
14911337SWilliam.Krier@Sun.COM | STANDARD_RIGHTS_EXECUTE
15011337SWilliam.Krier@Sun.COM | POLICY_VIEW_LOCAL_INFORMATION
15111337SWilliam.Krier@Sun.COM | POLICY_LOOKUP_NAMES;
15211337SWilliam.Krier@Sun.COM }
15311337SWilliam.Krier@Sun.COM
15411337SWilliam.Krier@Sun.COM if ((rc = ndr_rpc_call(lsa_handle, opnum, &arg)) != 0) {
15511337SWilliam.Krier@Sun.COM ndr_rpc_unbind(lsa_handle);
15611337SWilliam.Krier@Sun.COM return (-1);
15711337SWilliam.Krier@Sun.COM }
15811337SWilliam.Krier@Sun.COM
15911337SWilliam.Krier@Sun.COM if (arg.status != 0) {
16011337SWilliam.Krier@Sun.COM rc = -1;
16111337SWilliam.Krier@Sun.COM } else {
16211337SWilliam.Krier@Sun.COM (void) memcpy(&lsa_handle->handle, &arg.domain_handle,
16311337SWilliam.Krier@Sun.COM sizeof (ndr_hdid_t));
16411337SWilliam.Krier@Sun.COM
16511337SWilliam.Krier@Sun.COM if (ndr_is_null_handle(lsa_handle))
16611337SWilliam.Krier@Sun.COM rc = -1;
16711337SWilliam.Krier@Sun.COM }
16811337SWilliam.Krier@Sun.COM
16911337SWilliam.Krier@Sun.COM ndr_rpc_release(lsa_handle);
17011337SWilliam.Krier@Sun.COM
17111337SWilliam.Krier@Sun.COM if (rc != 0)
17211337SWilliam.Krier@Sun.COM ndr_rpc_unbind(lsa_handle);
17311337SWilliam.Krier@Sun.COM return (rc);
17411337SWilliam.Krier@Sun.COM }
17511337SWilliam.Krier@Sun.COM
17611337SWilliam.Krier@Sun.COM /*
17711337SWilliam.Krier@Sun.COM * lsar_open_account
17811337SWilliam.Krier@Sun.COM *
17911337SWilliam.Krier@Sun.COM * Obtain an LSA account handle. The lsa_handle must be a valid handle
18011337SWilliam.Krier@Sun.COM * obtained via lsar_open_policy2. The main thing to remember here is
18111337SWilliam.Krier@Sun.COM * to set up the context in the lsa_account_handle. I'm not sure what
18211337SWilliam.Krier@Sun.COM * the requirements are for desired access. Some values require admin
18311337SWilliam.Krier@Sun.COM * access.
18411337SWilliam.Krier@Sun.COM *
18511337SWilliam.Krier@Sun.COM * Returns 0 on success. Otherwise non-zero to indicate a failure.
18611337SWilliam.Krier@Sun.COM */
18711337SWilliam.Krier@Sun.COM int
lsar_open_account(mlsvc_handle_t * lsa_handle,struct mslsa_sid * sid,mlsvc_handle_t * lsa_account_handle)18811337SWilliam.Krier@Sun.COM lsar_open_account(mlsvc_handle_t *lsa_handle, struct mslsa_sid *sid,
18911337SWilliam.Krier@Sun.COM mlsvc_handle_t *lsa_account_handle)
19011337SWilliam.Krier@Sun.COM {
19111337SWilliam.Krier@Sun.COM struct mslsa_OpenAccount arg;
19211337SWilliam.Krier@Sun.COM int opnum;
19311337SWilliam.Krier@Sun.COM int rc;
19411337SWilliam.Krier@Sun.COM
19511337SWilliam.Krier@Sun.COM if (ndr_is_null_handle(lsa_handle) || sid == NULL)
19611337SWilliam.Krier@Sun.COM return (-1);
19711337SWilliam.Krier@Sun.COM
19811337SWilliam.Krier@Sun.COM opnum = LSARPC_OPNUM_OpenAccount;
19911337SWilliam.Krier@Sun.COM bzero(&arg, sizeof (struct mslsa_OpenAccount));
20011337SWilliam.Krier@Sun.COM
20111337SWilliam.Krier@Sun.COM (void) memcpy(&arg.handle, lsa_handle, sizeof (mslsa_handle_t));
20211337SWilliam.Krier@Sun.COM arg.sid = sid;
20311337SWilliam.Krier@Sun.COM arg.access_mask = STANDARD_RIGHTS_REQUIRED
20411337SWilliam.Krier@Sun.COM #if 0
20511337SWilliam.Krier@Sun.COM | POLICY_VIEW_AUDIT_INFORMATION
20611337SWilliam.Krier@Sun.COM | POLICY_GET_PRIVATE_INFORMATION
20711337SWilliam.Krier@Sun.COM | POLICY_TRUST_ADMIN
20811337SWilliam.Krier@Sun.COM #endif
20911337SWilliam.Krier@Sun.COM | POLICY_VIEW_LOCAL_INFORMATION;
21011337SWilliam.Krier@Sun.COM
21111337SWilliam.Krier@Sun.COM if ((rc = ndr_rpc_call(lsa_handle, opnum, &arg)) != 0)
21211337SWilliam.Krier@Sun.COM return (-1);
21311337SWilliam.Krier@Sun.COM
21411337SWilliam.Krier@Sun.COM if (arg.status != 0) {
21511337SWilliam.Krier@Sun.COM rc = -1;
21611337SWilliam.Krier@Sun.COM } else {
21711337SWilliam.Krier@Sun.COM ndr_inherit_handle(lsa_account_handle, lsa_handle);
21811337SWilliam.Krier@Sun.COM
21911337SWilliam.Krier@Sun.COM (void) memcpy(&lsa_account_handle->handle,
22011337SWilliam.Krier@Sun.COM &arg.account_handle, sizeof (ndr_hdid_t));
22111337SWilliam.Krier@Sun.COM
22211337SWilliam.Krier@Sun.COM if (ndr_is_null_handle(lsa_account_handle))
22311337SWilliam.Krier@Sun.COM rc = -1;
22411337SWilliam.Krier@Sun.COM }
22511337SWilliam.Krier@Sun.COM
22611337SWilliam.Krier@Sun.COM ndr_rpc_release(lsa_handle);
22711337SWilliam.Krier@Sun.COM return (rc);
22811337SWilliam.Krier@Sun.COM }
22911337SWilliam.Krier@Sun.COM
23011337SWilliam.Krier@Sun.COM /*
23111337SWilliam.Krier@Sun.COM * lsar_close
23211337SWilliam.Krier@Sun.COM *
23311337SWilliam.Krier@Sun.COM * Close the LSA connection associated with the handle. The lsa_handle
23411337SWilliam.Krier@Sun.COM * must be a valid handle obtained via a call to lsar_open_policy2 or
23511337SWilliam.Krier@Sun.COM * lsar_open_account. On success the handle will be zeroed out to
23611337SWilliam.Krier@Sun.COM * ensure that it is not used again. If this is the top level handle
23711337SWilliam.Krier@Sun.COM * (i.e. the one obtained via lsar_open_policy2) the pipe is closed.
23811337SWilliam.Krier@Sun.COM *
23911337SWilliam.Krier@Sun.COM * Returns 0 on success. Otherwise non-zero to indicate a failure.
24011337SWilliam.Krier@Sun.COM */
24111337SWilliam.Krier@Sun.COM int
lsar_close(mlsvc_handle_t * lsa_handle)24211337SWilliam.Krier@Sun.COM lsar_close(mlsvc_handle_t *lsa_handle)
24311337SWilliam.Krier@Sun.COM {
24411337SWilliam.Krier@Sun.COM struct mslsa_CloseHandle arg;
24511337SWilliam.Krier@Sun.COM int opnum;
24611337SWilliam.Krier@Sun.COM
24711337SWilliam.Krier@Sun.COM if (ndr_is_null_handle(lsa_handle))
24811337SWilliam.Krier@Sun.COM return (-1);
24911337SWilliam.Krier@Sun.COM
25011337SWilliam.Krier@Sun.COM opnum = LSARPC_OPNUM_CloseHandle;
25111337SWilliam.Krier@Sun.COM bzero(&arg, sizeof (struct mslsa_CloseHandle));
25211337SWilliam.Krier@Sun.COM (void) memcpy(&arg.handle, lsa_handle, sizeof (mslsa_handle_t));
25311337SWilliam.Krier@Sun.COM
25411337SWilliam.Krier@Sun.COM (void) ndr_rpc_call(lsa_handle, opnum, &arg);
25511337SWilliam.Krier@Sun.COM ndr_rpc_release(lsa_handle);
25611337SWilliam.Krier@Sun.COM
25711337SWilliam.Krier@Sun.COM if (ndr_is_bind_handle(lsa_handle))
25811337SWilliam.Krier@Sun.COM ndr_rpc_unbind(lsa_handle);
25911337SWilliam.Krier@Sun.COM
26011337SWilliam.Krier@Sun.COM bzero(lsa_handle, sizeof (mlsvc_handle_t));
26111337SWilliam.Krier@Sun.COM return (0);
26211337SWilliam.Krier@Sun.COM }
26311337SWilliam.Krier@Sun.COM
26411337SWilliam.Krier@Sun.COM /*
26511337SWilliam.Krier@Sun.COM * lsar_query_security_desc
26611337SWilliam.Krier@Sun.COM *
26711337SWilliam.Krier@Sun.COM * Don't use this call yet. It is just a place holder for now.
26811337SWilliam.Krier@Sun.COM */
26911337SWilliam.Krier@Sun.COM int
lsar_query_security_desc(mlsvc_handle_t * lsa_handle)27011337SWilliam.Krier@Sun.COM lsar_query_security_desc(mlsvc_handle_t *lsa_handle)
27111337SWilliam.Krier@Sun.COM {
27211337SWilliam.Krier@Sun.COM struct mslsa_QuerySecurityObject arg;
27311337SWilliam.Krier@Sun.COM int rc;
27411337SWilliam.Krier@Sun.COM int opnum;
27511337SWilliam.Krier@Sun.COM
27611337SWilliam.Krier@Sun.COM opnum = LSARPC_OPNUM_QuerySecurityObject;
27711337SWilliam.Krier@Sun.COM
27811337SWilliam.Krier@Sun.COM bzero(&arg, sizeof (struct mslsa_QuerySecurityObject));
27911337SWilliam.Krier@Sun.COM (void) memcpy(&arg.handle, lsa_handle, sizeof (mslsa_handle_t));
28011337SWilliam.Krier@Sun.COM
28111337SWilliam.Krier@Sun.COM rc = ndr_rpc_call(lsa_handle, opnum, &arg);
28211337SWilliam.Krier@Sun.COM ndr_rpc_release(lsa_handle);
28311337SWilliam.Krier@Sun.COM return (rc);
28411337SWilliam.Krier@Sun.COM }
28511337SWilliam.Krier@Sun.COM
28611337SWilliam.Krier@Sun.COM /*
28711337SWilliam.Krier@Sun.COM * lsar_query_info_policy
28811337SWilliam.Krier@Sun.COM *
28911337SWilliam.Krier@Sun.COM * The general purpose of this function is to allow various pieces of
29011337SWilliam.Krier@Sun.COM * information to be queried on the domain controller. The only
29111337SWilliam.Krier@Sun.COM * information queries supported are MSLSA_POLICY_PRIMARY_DOMAIN_INFO
29211337SWilliam.Krier@Sun.COM * and MSLSA_POLICY_ACCOUNT_DOMAIN_INFO.
29311337SWilliam.Krier@Sun.COM *
29411337SWilliam.Krier@Sun.COM * On success, the return code will be 0 and the user_info structure
29511337SWilliam.Krier@Sun.COM * will be set up. The sid_name_use field will be set to SidTypeDomain
29611337SWilliam.Krier@Sun.COM * indicating that the domain name and domain sid fields are vaild. If
29711337SWilliam.Krier@Sun.COM * the infoClass returned from the server is not one of the supported
29811337SWilliam.Krier@Sun.COM * values, the sid_name_use willbe set to SidTypeUnknown. If the RPC
29911337SWilliam.Krier@Sun.COM * fails, a negative error code will be returned, in which case the
30011337SWilliam.Krier@Sun.COM * user_info will not have been updated.
30111337SWilliam.Krier@Sun.COM */
30211337SWilliam.Krier@Sun.COM DWORD
lsar_query_info_policy(mlsvc_handle_t * lsa_handle,WORD infoClass,smb_domain_t * info)30311337SWilliam.Krier@Sun.COM lsar_query_info_policy(mlsvc_handle_t *lsa_handle, WORD infoClass,
30411337SWilliam.Krier@Sun.COM smb_domain_t *info)
30511337SWilliam.Krier@Sun.COM {
30611337SWilliam.Krier@Sun.COM struct mslsa_QueryInfoPolicy arg;
30711337SWilliam.Krier@Sun.COM struct mslsa_PrimaryDomainInfo *pd_info;
30811337SWilliam.Krier@Sun.COM struct mslsa_AccountDomainInfo *ad_info;
30911337SWilliam.Krier@Sun.COM struct mslsa_DnsDomainInfo *dns_info;
31011337SWilliam.Krier@Sun.COM char guid_str[UUID_PRINTABLE_STRING_LENGTH];
31111337SWilliam.Krier@Sun.COM char sidstr[SMB_SID_STRSZ];
31211337SWilliam.Krier@Sun.COM int opnum;
31311337SWilliam.Krier@Sun.COM DWORD status;
31411337SWilliam.Krier@Sun.COM
31511337SWilliam.Krier@Sun.COM if (lsa_handle == NULL || info == NULL)
31611337SWilliam.Krier@Sun.COM return (NT_STATUS_INVALID_PARAMETER);
31711337SWilliam.Krier@Sun.COM
31811337SWilliam.Krier@Sun.COM opnum = LSARPC_OPNUM_QueryInfoPolicy;
31911337SWilliam.Krier@Sun.COM
32011337SWilliam.Krier@Sun.COM bzero(info, sizeof (smb_domain_t));
32111337SWilliam.Krier@Sun.COM bzero(&arg, sizeof (struct mslsa_QueryInfoPolicy));
32211337SWilliam.Krier@Sun.COM (void) memcpy(&arg.handle, lsa_handle, sizeof (mslsa_handle_t));
32311337SWilliam.Krier@Sun.COM
32411337SWilliam.Krier@Sun.COM arg.info_class = infoClass;
32511337SWilliam.Krier@Sun.COM
32611337SWilliam.Krier@Sun.COM if (ndr_rpc_call(lsa_handle, opnum, &arg) != 0) {
32711337SWilliam.Krier@Sun.COM status = NT_STATUS_INVALID_PARAMETER;
32811337SWilliam.Krier@Sun.COM } else if (arg.status != 0) {
32911337SWilliam.Krier@Sun.COM ndr_rpc_status(lsa_handle, opnum, arg.status);
33011337SWilliam.Krier@Sun.COM status = NT_SC_VALUE(arg.status);
33111337SWilliam.Krier@Sun.COM } else {
33211337SWilliam.Krier@Sun.COM
33311337SWilliam.Krier@Sun.COM switch (infoClass) {
33411337SWilliam.Krier@Sun.COM case MSLSA_POLICY_PRIMARY_DOMAIN_INFO:
33511337SWilliam.Krier@Sun.COM pd_info = &arg.ru.pd_info;
33611337SWilliam.Krier@Sun.COM
33711337SWilliam.Krier@Sun.COM smb_sid_tostr((smb_sid_t *)pd_info->sid, sidstr);
33811337SWilliam.Krier@Sun.COM info->di_type = SMB_DOMAIN_PRIMARY;
33911337SWilliam.Krier@Sun.COM smb_domain_set_basic_info(sidstr,
34011337SWilliam.Krier@Sun.COM (char *)pd_info->name.str, "", info);
34111337SWilliam.Krier@Sun.COM
34211337SWilliam.Krier@Sun.COM status = NT_STATUS_SUCCESS;
34311337SWilliam.Krier@Sun.COM break;
34411337SWilliam.Krier@Sun.COM
34511337SWilliam.Krier@Sun.COM case MSLSA_POLICY_ACCOUNT_DOMAIN_INFO:
34611337SWilliam.Krier@Sun.COM ad_info = &arg.ru.ad_info;
34711337SWilliam.Krier@Sun.COM
34811337SWilliam.Krier@Sun.COM smb_sid_tostr((smb_sid_t *)ad_info->sid, sidstr);
34911337SWilliam.Krier@Sun.COM info->di_type = SMB_DOMAIN_ACCOUNT;
35011337SWilliam.Krier@Sun.COM smb_domain_set_basic_info(sidstr,
35111337SWilliam.Krier@Sun.COM (char *)ad_info->name.str, "", info);
35211337SWilliam.Krier@Sun.COM
35311337SWilliam.Krier@Sun.COM status = NT_STATUS_SUCCESS;
35411337SWilliam.Krier@Sun.COM break;
35511337SWilliam.Krier@Sun.COM
35611337SWilliam.Krier@Sun.COM case MSLSA_POLICY_DNS_DOMAIN_INFO:
35711337SWilliam.Krier@Sun.COM dns_info = &arg.ru.dns_info;
35811337SWilliam.Krier@Sun.COM ndr_uuid_unparse((ndr_uuid_t *)&dns_info->guid,
35911337SWilliam.Krier@Sun.COM guid_str);
36011337SWilliam.Krier@Sun.COM smb_sid_tostr((smb_sid_t *)dns_info->sid, sidstr);
36111337SWilliam.Krier@Sun.COM
36211337SWilliam.Krier@Sun.COM info->di_type = SMB_DOMAIN_PRIMARY;
36311337SWilliam.Krier@Sun.COM smb_domain_set_dns_info(sidstr,
36411337SWilliam.Krier@Sun.COM (char *)dns_info->nb_domain.str,
36511337SWilliam.Krier@Sun.COM (char *)dns_info->dns_domain.str,
36611337SWilliam.Krier@Sun.COM (char *)dns_info->forest.str,
36711337SWilliam.Krier@Sun.COM guid_str, info);
36811337SWilliam.Krier@Sun.COM status = NT_STATUS_SUCCESS;
36911337SWilliam.Krier@Sun.COM break;
37011337SWilliam.Krier@Sun.COM
37111337SWilliam.Krier@Sun.COM default:
37211337SWilliam.Krier@Sun.COM status = NT_STATUS_INVALID_INFO_CLASS;
37311337SWilliam.Krier@Sun.COM break;
37411337SWilliam.Krier@Sun.COM }
37511337SWilliam.Krier@Sun.COM }
37611337SWilliam.Krier@Sun.COM
37711337SWilliam.Krier@Sun.COM ndr_rpc_release(lsa_handle);
37811337SWilliam.Krier@Sun.COM return (status);
37911337SWilliam.Krier@Sun.COM }
38011337SWilliam.Krier@Sun.COM
38111337SWilliam.Krier@Sun.COM /*
38211337SWilliam.Krier@Sun.COM * Lookup a name and obtain the sid/rid.
38311337SWilliam.Krier@Sun.COM * This is a wrapper for the various lookup sid RPCs.
38411337SWilliam.Krier@Sun.COM */
38511337SWilliam.Krier@Sun.COM uint32_t
lsar_lookup_names(mlsvc_handle_t * lsa_handle,char * name,smb_account_t * info)38611337SWilliam.Krier@Sun.COM lsar_lookup_names(mlsvc_handle_t *lsa_handle, char *name, smb_account_t *info)
38711337SWilliam.Krier@Sun.COM {
38811337SWilliam.Krier@Sun.COM static lsar_nameop_t ops[] = {
38911337SWilliam.Krier@Sun.COM lsar_lookup_names3,
39011337SWilliam.Krier@Sun.COM lsar_lookup_names2,
39111337SWilliam.Krier@Sun.COM lsar_lookup_names1
39211337SWilliam.Krier@Sun.COM };
39311337SWilliam.Krier@Sun.COM
39411337SWilliam.Krier@Sun.COM const srvsvc_server_info_t *svinfo;
39511337SWilliam.Krier@Sun.COM lsa_names_t names;
39611337SWilliam.Krier@Sun.COM char *p;
39711337SWilliam.Krier@Sun.COM uint32_t length;
39811337SWilliam.Krier@Sun.COM uint32_t status = NT_STATUS_INVALID_PARAMETER;
39911337SWilliam.Krier@Sun.COM int n_op = (sizeof (ops) / sizeof (ops[0]));
40011337SWilliam.Krier@Sun.COM int i;
40111337SWilliam.Krier@Sun.COM
40211337SWilliam.Krier@Sun.COM if (lsa_handle == NULL || name == NULL || info == NULL)
40311337SWilliam.Krier@Sun.COM return (NT_STATUS_INVALID_PARAMETER);
40411337SWilliam.Krier@Sun.COM
40511337SWilliam.Krier@Sun.COM bzero(info, sizeof (smb_account_t));
40611337SWilliam.Krier@Sun.COM
40711337SWilliam.Krier@Sun.COM svinfo = ndr_rpc_server_info(lsa_handle);
40811337SWilliam.Krier@Sun.COM if (svinfo->sv_os == NATIVE_OS_WIN2000 &&
40911337SWilliam.Krier@Sun.COM svinfo->sv_version_major == 5 && svinfo->sv_version_minor == 0) {
41011337SWilliam.Krier@Sun.COM /*
41111337SWilliam.Krier@Sun.COM * Windows 2000 doesn't like an LSA lookup for
41211337SWilliam.Krier@Sun.COM * DOMAIN\Administrator.
41311337SWilliam.Krier@Sun.COM */
41411337SWilliam.Krier@Sun.COM if ((p = strchr(name, '\\')) != 0) {
41511337SWilliam.Krier@Sun.COM ++p;
41611337SWilliam.Krier@Sun.COM
41711337SWilliam.Krier@Sun.COM if (strcasecmp(p, "administrator") == 0)
41811337SWilliam.Krier@Sun.COM name = p;
41911337SWilliam.Krier@Sun.COM }
42011337SWilliam.Krier@Sun.COM
42111337SWilliam.Krier@Sun.COM }
42211337SWilliam.Krier@Sun.COM
42311337SWilliam.Krier@Sun.COM length = smb_wcequiv_strlen(name);
42411337SWilliam.Krier@Sun.COM names.name[0].length = length;
42511337SWilliam.Krier@Sun.COM names.name[0].allosize = length;
42611337SWilliam.Krier@Sun.COM names.name[0].str = (unsigned char *)name;
42711337SWilliam.Krier@Sun.COM names.n_entry = 1;
42811337SWilliam.Krier@Sun.COM
42911337SWilliam.Krier@Sun.COM if (ndr_rpc_server_os(lsa_handle) == NATIVE_OS_WIN2000) {
43011337SWilliam.Krier@Sun.COM for (i = 0; i < n_op; ++i) {
43111337SWilliam.Krier@Sun.COM ndr_rpc_set_nonull(lsa_handle);
43211337SWilliam.Krier@Sun.COM status = (*ops[i])(lsa_handle, &names, info);
43311337SWilliam.Krier@Sun.COM
43411337SWilliam.Krier@Sun.COM if (status != NT_STATUS_INVALID_PARAMETER)
43511337SWilliam.Krier@Sun.COM break;
43611337SWilliam.Krier@Sun.COM }
43711337SWilliam.Krier@Sun.COM } else {
43811337SWilliam.Krier@Sun.COM ndr_rpc_set_nonull(lsa_handle);
43911337SWilliam.Krier@Sun.COM status = lsar_lookup_names1(lsa_handle, &names, info);
44011337SWilliam.Krier@Sun.COM }
44111337SWilliam.Krier@Sun.COM
44211337SWilliam.Krier@Sun.COM if (status == NT_STATUS_SUCCESS) {
44311337SWilliam.Krier@Sun.COM info->a_name = lsar_get_username(name);
44411337SWilliam.Krier@Sun.COM
44511337SWilliam.Krier@Sun.COM if (!smb_account_validate(info)) {
44611337SWilliam.Krier@Sun.COM smb_account_free(info);
44711337SWilliam.Krier@Sun.COM status = NT_STATUS_NO_MEMORY;
44811337SWilliam.Krier@Sun.COM } else {
44911337SWilliam.Krier@Sun.COM smb_account_trace(info);
45011337SWilliam.Krier@Sun.COM }
45111337SWilliam.Krier@Sun.COM }
45211337SWilliam.Krier@Sun.COM
45311337SWilliam.Krier@Sun.COM return (status);
45411337SWilliam.Krier@Sun.COM }
45511337SWilliam.Krier@Sun.COM
45611337SWilliam.Krier@Sun.COM /*
45711337SWilliam.Krier@Sun.COM * The name may be in one of the following forms:
45811337SWilliam.Krier@Sun.COM *
45911337SWilliam.Krier@Sun.COM * domain\username
46011337SWilliam.Krier@Sun.COM * domain/username
46111337SWilliam.Krier@Sun.COM * username
46211337SWilliam.Krier@Sun.COM * username@domain
46311337SWilliam.Krier@Sun.COM *
46411337SWilliam.Krier@Sun.COM * Return a strdup'd copy of the username. The caller is responsible
46511337SWilliam.Krier@Sun.COM * for freeing the allocated memory.
46611337SWilliam.Krier@Sun.COM */
46711337SWilliam.Krier@Sun.COM static char *
lsar_get_username(const char * name)46811337SWilliam.Krier@Sun.COM lsar_get_username(const char *name)
46911337SWilliam.Krier@Sun.COM {
47011337SWilliam.Krier@Sun.COM char tmp[MAXNAMELEN];
47111337SWilliam.Krier@Sun.COM char *dp = NULL;
47211337SWilliam.Krier@Sun.COM char *np = NULL;
47311337SWilliam.Krier@Sun.COM
47411337SWilliam.Krier@Sun.COM (void) strlcpy(tmp, name, MAXNAMELEN);
47511337SWilliam.Krier@Sun.COM smb_name_parse(tmp, &np, &dp);
47611337SWilliam.Krier@Sun.COM
47711337SWilliam.Krier@Sun.COM if (dp != NULL && np != NULL)
47811337SWilliam.Krier@Sun.COM return (strdup(np));
47911337SWilliam.Krier@Sun.COM else
48011337SWilliam.Krier@Sun.COM return (strdup(name));
48111337SWilliam.Krier@Sun.COM }
48211337SWilliam.Krier@Sun.COM
48311337SWilliam.Krier@Sun.COM /*
48411337SWilliam.Krier@Sun.COM * lsar_lookup_names1
48511337SWilliam.Krier@Sun.COM *
48611337SWilliam.Krier@Sun.COM * Lookup a name and obtain the domain and user rid.
48711337SWilliam.Krier@Sun.COM *
48811337SWilliam.Krier@Sun.COM * Note: NT returns an error if the mapped_count is non-zero when the RPC
48911337SWilliam.Krier@Sun.COM * is called.
49011337SWilliam.Krier@Sun.COM *
49111337SWilliam.Krier@Sun.COM * If the lookup fails, the status will typically be NT_STATUS_NONE_MAPPED.
49211337SWilliam.Krier@Sun.COM */
49311337SWilliam.Krier@Sun.COM static uint32_t
lsar_lookup_names1(mlsvc_handle_t * lsa_handle,lsa_names_t * names,smb_account_t * info)49411337SWilliam.Krier@Sun.COM lsar_lookup_names1(mlsvc_handle_t *lsa_handle, lsa_names_t *names,
49511337SWilliam.Krier@Sun.COM smb_account_t *info)
49611337SWilliam.Krier@Sun.COM {
49711337SWilliam.Krier@Sun.COM struct mslsa_LookupNames arg;
49811337SWilliam.Krier@Sun.COM struct mslsa_rid_entry *rid_entry;
49911337SWilliam.Krier@Sun.COM struct mslsa_domain_entry *domain_entry;
50011337SWilliam.Krier@Sun.COM uint32_t status = NT_STATUS_SUCCESS;
50111337SWilliam.Krier@Sun.COM char *domname;
50211337SWilliam.Krier@Sun.COM int opnum = LSARPC_OPNUM_LookupNames;
50311337SWilliam.Krier@Sun.COM
50411337SWilliam.Krier@Sun.COM bzero(&arg, sizeof (struct mslsa_LookupNames));
50511337SWilliam.Krier@Sun.COM (void) memcpy(&arg.handle, lsa_handle, sizeof (mslsa_handle_t));
50611337SWilliam.Krier@Sun.COM arg.lookup_level = LSA_LOOKUP_WKSTA;
50711337SWilliam.Krier@Sun.COM arg.name_table = (struct mslsa_lup_name_table *)names;
50811337SWilliam.Krier@Sun.COM
50911337SWilliam.Krier@Sun.COM if (ndr_rpc_call(lsa_handle, opnum, &arg) != 0) {
51011337SWilliam.Krier@Sun.COM ndr_rpc_release(lsa_handle);
51111337SWilliam.Krier@Sun.COM return (NT_STATUS_INVALID_PARAMETER);
51211337SWilliam.Krier@Sun.COM }
51311337SWilliam.Krier@Sun.COM
51411337SWilliam.Krier@Sun.COM if (arg.status != NT_STATUS_SUCCESS) {
51511337SWilliam.Krier@Sun.COM ndr_rpc_status(lsa_handle, opnum, arg.status);
51611337SWilliam.Krier@Sun.COM ndr_rpc_release(lsa_handle);
51711337SWilliam.Krier@Sun.COM return (NT_SC_VALUE(arg.status));
51811337SWilliam.Krier@Sun.COM }
51911337SWilliam.Krier@Sun.COM
52011337SWilliam.Krier@Sun.COM if (arg.mapped_count == 0) {
52111337SWilliam.Krier@Sun.COM ndr_rpc_release(lsa_handle);
52211337SWilliam.Krier@Sun.COM return (NT_STATUS_NONE_MAPPED);
52311337SWilliam.Krier@Sun.COM }
52411337SWilliam.Krier@Sun.COM
52511337SWilliam.Krier@Sun.COM rid_entry = &arg.translated_sids.rids[0];
52611337SWilliam.Krier@Sun.COM if (rid_entry->domain_index != 0) {
52711337SWilliam.Krier@Sun.COM ndr_rpc_release(lsa_handle);
52811337SWilliam.Krier@Sun.COM return (NT_STATUS_NONE_MAPPED);
52911337SWilliam.Krier@Sun.COM }
53011337SWilliam.Krier@Sun.COM
53111337SWilliam.Krier@Sun.COM domain_entry = &arg.domain_table->entries[0];
53211337SWilliam.Krier@Sun.COM
53311337SWilliam.Krier@Sun.COM info->a_type = rid_entry->sid_name_use;
53411337SWilliam.Krier@Sun.COM info->a_domsid = smb_sid_dup((smb_sid_t *)domain_entry->domain_sid);
53511337SWilliam.Krier@Sun.COM if ((domname = (char *)domain_entry->domain_name.str) != NULL)
53611337SWilliam.Krier@Sun.COM info->a_domain = strdup(domname);
53711337SWilliam.Krier@Sun.COM info->a_rid = rid_entry->rid;
53811337SWilliam.Krier@Sun.COM info->a_sid = smb_sid_splice(info->a_domsid, info->a_rid);
53911337SWilliam.Krier@Sun.COM
54011337SWilliam.Krier@Sun.COM ndr_rpc_release(lsa_handle);
54111337SWilliam.Krier@Sun.COM return (status);
54211337SWilliam.Krier@Sun.COM }
54311337SWilliam.Krier@Sun.COM
54411337SWilliam.Krier@Sun.COM /*
54511337SWilliam.Krier@Sun.COM * lsar_lookup_names2
54611337SWilliam.Krier@Sun.COM */
54711337SWilliam.Krier@Sun.COM static uint32_t
lsar_lookup_names2(mlsvc_handle_t * lsa_handle,lsa_names_t * names,smb_account_t * info)54811337SWilliam.Krier@Sun.COM lsar_lookup_names2(mlsvc_handle_t *lsa_handle, lsa_names_t *names,
54911337SWilliam.Krier@Sun.COM smb_account_t *info)
55011337SWilliam.Krier@Sun.COM {
55111337SWilliam.Krier@Sun.COM struct lsar_LookupNames2 arg;
55211337SWilliam.Krier@Sun.COM struct lsar_rid_entry2 *rid_entry;
55311337SWilliam.Krier@Sun.COM struct mslsa_domain_entry *domain_entry;
55411337SWilliam.Krier@Sun.COM uint32_t status = NT_STATUS_SUCCESS;
55511337SWilliam.Krier@Sun.COM char *domname;
55611337SWilliam.Krier@Sun.COM int opnum = LSARPC_OPNUM_LookupNames2;
55711337SWilliam.Krier@Sun.COM
55811337SWilliam.Krier@Sun.COM bzero(&arg, sizeof (struct lsar_LookupNames2));
55911337SWilliam.Krier@Sun.COM (void) memcpy(&arg.policy_handle, lsa_handle, sizeof (mslsa_handle_t));
56011337SWilliam.Krier@Sun.COM arg.lookup_level = LSA_LOOKUP_WKSTA;
56111337SWilliam.Krier@Sun.COM arg.client_revision = LSA_CLIENT_REVISION_AD;
56211337SWilliam.Krier@Sun.COM arg.name_table = (struct mslsa_lup_name_table *)names;
56311337SWilliam.Krier@Sun.COM
56411337SWilliam.Krier@Sun.COM if (ndr_rpc_call(lsa_handle, opnum, &arg) != 0) {
56511337SWilliam.Krier@Sun.COM ndr_rpc_release(lsa_handle);
56611337SWilliam.Krier@Sun.COM return (NT_STATUS_INVALID_PARAMETER);
56711337SWilliam.Krier@Sun.COM }
56811337SWilliam.Krier@Sun.COM
56911337SWilliam.Krier@Sun.COM if (arg.status != NT_STATUS_SUCCESS) {
57011337SWilliam.Krier@Sun.COM ndr_rpc_status(lsa_handle, opnum, arg.status);
57111337SWilliam.Krier@Sun.COM ndr_rpc_release(lsa_handle);
57211337SWilliam.Krier@Sun.COM return (NT_SC_VALUE(arg.status));
57311337SWilliam.Krier@Sun.COM }
57411337SWilliam.Krier@Sun.COM
57511337SWilliam.Krier@Sun.COM if (arg.mapped_count == 0) {
57611337SWilliam.Krier@Sun.COM ndr_rpc_release(lsa_handle);
57711337SWilliam.Krier@Sun.COM return (NT_STATUS_NONE_MAPPED);
57811337SWilliam.Krier@Sun.COM }
57911337SWilliam.Krier@Sun.COM
58011337SWilliam.Krier@Sun.COM rid_entry = &arg.translated_sids.rids[0];
58111337SWilliam.Krier@Sun.COM if (rid_entry->domain_index != 0) {
58211337SWilliam.Krier@Sun.COM ndr_rpc_release(lsa_handle);
58311337SWilliam.Krier@Sun.COM return (NT_STATUS_NONE_MAPPED);
58411337SWilliam.Krier@Sun.COM }
58511337SWilliam.Krier@Sun.COM
58611337SWilliam.Krier@Sun.COM domain_entry = &arg.domain_table->entries[0];
58711337SWilliam.Krier@Sun.COM
58811337SWilliam.Krier@Sun.COM info->a_type = rid_entry->sid_name_use;
58911337SWilliam.Krier@Sun.COM info->a_domsid = smb_sid_dup((smb_sid_t *)domain_entry->domain_sid);
59011337SWilliam.Krier@Sun.COM if ((domname = (char *)domain_entry->domain_name.str) != NULL)
59111337SWilliam.Krier@Sun.COM info->a_domain = strdup(domname);
59211337SWilliam.Krier@Sun.COM info->a_rid = rid_entry->rid;
59311337SWilliam.Krier@Sun.COM info->a_sid = smb_sid_splice(info->a_domsid, info->a_rid);
59411337SWilliam.Krier@Sun.COM
59511337SWilliam.Krier@Sun.COM ndr_rpc_release(lsa_handle);
59611337SWilliam.Krier@Sun.COM return (status);
59711337SWilliam.Krier@Sun.COM }
59811337SWilliam.Krier@Sun.COM
59911337SWilliam.Krier@Sun.COM /*
60011337SWilliam.Krier@Sun.COM * lsar_lookup_names3
60111337SWilliam.Krier@Sun.COM */
60211337SWilliam.Krier@Sun.COM static uint32_t
lsar_lookup_names3(mlsvc_handle_t * lsa_handle,lsa_names_t * names,smb_account_t * info)60311337SWilliam.Krier@Sun.COM lsar_lookup_names3(mlsvc_handle_t *lsa_handle, lsa_names_t *names,
60411337SWilliam.Krier@Sun.COM smb_account_t *info)
60511337SWilliam.Krier@Sun.COM {
60611337SWilliam.Krier@Sun.COM struct lsar_LookupNames3 arg;
60711337SWilliam.Krier@Sun.COM lsar_translated_sid_ex2_t *sid_entry;
60811337SWilliam.Krier@Sun.COM struct mslsa_domain_entry *domain_entry;
60911337SWilliam.Krier@Sun.COM uint32_t status = NT_STATUS_SUCCESS;
61011337SWilliam.Krier@Sun.COM char *domname;
61111337SWilliam.Krier@Sun.COM int opnum = LSARPC_OPNUM_LookupNames3;
61211337SWilliam.Krier@Sun.COM
61311337SWilliam.Krier@Sun.COM bzero(&arg, sizeof (struct lsar_LookupNames3));
61411337SWilliam.Krier@Sun.COM (void) memcpy(&arg.policy_handle, lsa_handle, sizeof (mslsa_handle_t));
61511337SWilliam.Krier@Sun.COM arg.lookup_level = LSA_LOOKUP_WKSTA;
61611337SWilliam.Krier@Sun.COM arg.client_revision = LSA_CLIENT_REVISION_AD;
61711337SWilliam.Krier@Sun.COM arg.name_table = (struct mslsa_lup_name_table *)names;
61811337SWilliam.Krier@Sun.COM
61911337SWilliam.Krier@Sun.COM if (ndr_rpc_call(lsa_handle, opnum, &arg) != 0) {
62011337SWilliam.Krier@Sun.COM ndr_rpc_release(lsa_handle);
62111337SWilliam.Krier@Sun.COM return (NT_STATUS_INVALID_PARAMETER);
62211337SWilliam.Krier@Sun.COM }
62311337SWilliam.Krier@Sun.COM
62411337SWilliam.Krier@Sun.COM if (arg.status != NT_STATUS_SUCCESS) {
62511337SWilliam.Krier@Sun.COM ndr_rpc_status(lsa_handle, opnum, arg.status);
62611337SWilliam.Krier@Sun.COM ndr_rpc_release(lsa_handle);
62711337SWilliam.Krier@Sun.COM return (NT_SC_VALUE(arg.status));
62811337SWilliam.Krier@Sun.COM }
62911337SWilliam.Krier@Sun.COM
63011337SWilliam.Krier@Sun.COM if (arg.mapped_count == 0) {
63111337SWilliam.Krier@Sun.COM ndr_rpc_release(lsa_handle);
63211337SWilliam.Krier@Sun.COM return (NT_STATUS_NONE_MAPPED);
63311337SWilliam.Krier@Sun.COM }
63411337SWilliam.Krier@Sun.COM
63511337SWilliam.Krier@Sun.COM sid_entry = &arg.translated_sids.sids[0];
63611337SWilliam.Krier@Sun.COM if (sid_entry->domain_index != 0) {
63711337SWilliam.Krier@Sun.COM ndr_rpc_release(lsa_handle);
63811337SWilliam.Krier@Sun.COM return (NT_STATUS_NONE_MAPPED);
63911337SWilliam.Krier@Sun.COM }
64011337SWilliam.Krier@Sun.COM
64111337SWilliam.Krier@Sun.COM domain_entry = &arg.domain_table->entries[0];
64211337SWilliam.Krier@Sun.COM
64311337SWilliam.Krier@Sun.COM info->a_type = sid_entry->sid_name_use;
64411337SWilliam.Krier@Sun.COM info->a_domsid = smb_sid_dup((smb_sid_t *)domain_entry->domain_sid);
64511337SWilliam.Krier@Sun.COM if ((domname = (char *)domain_entry->domain_name.str) != NULL)
64611337SWilliam.Krier@Sun.COM info->a_domain = strdup(domname);
64711337SWilliam.Krier@Sun.COM info->a_sid = smb_sid_dup((smb_sid_t *)sid_entry->sid);
64811337SWilliam.Krier@Sun.COM (void) smb_sid_getrid(info->a_sid, &info->a_rid);
64911337SWilliam.Krier@Sun.COM
65011337SWilliam.Krier@Sun.COM ndr_rpc_release(lsa_handle);
65111337SWilliam.Krier@Sun.COM return (status);
65211337SWilliam.Krier@Sun.COM }
65311337SWilliam.Krier@Sun.COM
65411337SWilliam.Krier@Sun.COM /*
65511337SWilliam.Krier@Sun.COM * lsar_lookup_names4
65611337SWilliam.Krier@Sun.COM *
65711337SWilliam.Krier@Sun.COM * This function is only valid if the remote RPC server is a domain
65811337SWilliam.Krier@Sun.COM * controller and requires the security extensions defined in MS-RPCE.
65911337SWilliam.Krier@Sun.COM *
66011337SWilliam.Krier@Sun.COM * Domain controllers will return RPC_NT_PROTSEQ_NOT_SUPPORTED here
66111337SWilliam.Krier@Sun.COM * because we don't support the RPC_C_AUTHN_NETLOGON security provider.
66211337SWilliam.Krier@Sun.COM * Non-domain controllers will return NT_STATUS_INVALID_SERVER_STATE.
66311337SWilliam.Krier@Sun.COM */
66411337SWilliam.Krier@Sun.COM static uint32_t /*LINTED E_STATIC_UNUSED*/
lsar_lookup_names4(mlsvc_handle_t * lsa_handle,lsa_names_t * names,smb_account_t * info)66511337SWilliam.Krier@Sun.COM lsar_lookup_names4(mlsvc_handle_t *lsa_handle, lsa_names_t *names,
66611337SWilliam.Krier@Sun.COM smb_account_t *info)
66711337SWilliam.Krier@Sun.COM {
66811337SWilliam.Krier@Sun.COM struct lsar_LookupNames4 arg;
66911337SWilliam.Krier@Sun.COM lsar_translated_sid_ex2_t *sid_entry;
67011337SWilliam.Krier@Sun.COM struct mslsa_domain_entry *domain_entry;
67111337SWilliam.Krier@Sun.COM uint32_t status = NT_STATUS_SUCCESS;
67211337SWilliam.Krier@Sun.COM char *domname;
67311337SWilliam.Krier@Sun.COM int opnum = LSARPC_OPNUM_LookupNames4;
67411337SWilliam.Krier@Sun.COM
67511337SWilliam.Krier@Sun.COM bzero(&arg, sizeof (struct lsar_LookupNames4));
67611337SWilliam.Krier@Sun.COM arg.lookup_level = LSA_LOOKUP_WKSTA;
67711337SWilliam.Krier@Sun.COM arg.client_revision = LSA_CLIENT_REVISION_AD;
67811337SWilliam.Krier@Sun.COM arg.name_table = (struct mslsa_lup_name_table *)names;
67911337SWilliam.Krier@Sun.COM
68011337SWilliam.Krier@Sun.COM if (ndr_rpc_call(lsa_handle, opnum, &arg) != 0) {
68111337SWilliam.Krier@Sun.COM ndr_rpc_release(lsa_handle);
68211337SWilliam.Krier@Sun.COM return (NT_STATUS_INVALID_PARAMETER);
68311337SWilliam.Krier@Sun.COM }
68411337SWilliam.Krier@Sun.COM
68511337SWilliam.Krier@Sun.COM if (arg.status != NT_STATUS_SUCCESS) {
68611337SWilliam.Krier@Sun.COM ndr_rpc_status(lsa_handle, opnum, arg.status);
68711337SWilliam.Krier@Sun.COM ndr_rpc_release(lsa_handle);
68811337SWilliam.Krier@Sun.COM if (arg.status == RPC_NT_PROTSEQ_NOT_SUPPORTED ||
68911337SWilliam.Krier@Sun.COM arg.status == NT_STATUS_INVALID_SERVER_STATE)
69011337SWilliam.Krier@Sun.COM return (NT_STATUS_INVALID_PARAMETER);
69111337SWilliam.Krier@Sun.COM return (NT_SC_VALUE(arg.status));
69211337SWilliam.Krier@Sun.COM }
69311337SWilliam.Krier@Sun.COM
69411337SWilliam.Krier@Sun.COM if (arg.mapped_count == 0) {
69511337SWilliam.Krier@Sun.COM ndr_rpc_release(lsa_handle);
69611337SWilliam.Krier@Sun.COM return (NT_STATUS_NONE_MAPPED);
69711337SWilliam.Krier@Sun.COM }
69811337SWilliam.Krier@Sun.COM
69911337SWilliam.Krier@Sun.COM sid_entry = &arg.translated_sids.sids[0];
70011337SWilliam.Krier@Sun.COM if (sid_entry->domain_index != 0) {
70111337SWilliam.Krier@Sun.COM ndr_rpc_release(lsa_handle);
70211337SWilliam.Krier@Sun.COM return (NT_STATUS_NONE_MAPPED);
70311337SWilliam.Krier@Sun.COM }
70411337SWilliam.Krier@Sun.COM
70511337SWilliam.Krier@Sun.COM domain_entry = &arg.domain_table->entries[0];
70611337SWilliam.Krier@Sun.COM
70711337SWilliam.Krier@Sun.COM info->a_type = sid_entry->sid_name_use;
70811337SWilliam.Krier@Sun.COM info->a_domsid = smb_sid_dup((smb_sid_t *)domain_entry->domain_sid);
70911337SWilliam.Krier@Sun.COM if ((domname = (char *)domain_entry->domain_name.str) != NULL)
71011337SWilliam.Krier@Sun.COM info->a_domain = strdup(domname);
71111337SWilliam.Krier@Sun.COM info->a_sid = smb_sid_dup((smb_sid_t *)sid_entry->sid);
71211337SWilliam.Krier@Sun.COM (void) smb_sid_getrid(info->a_sid, &info->a_rid);
71311337SWilliam.Krier@Sun.COM
71411337SWilliam.Krier@Sun.COM ndr_rpc_release(lsa_handle);
71511337SWilliam.Krier@Sun.COM return (status);
71611337SWilliam.Krier@Sun.COM }
71711337SWilliam.Krier@Sun.COM
71811337SWilliam.Krier@Sun.COM /*
71911337SWilliam.Krier@Sun.COM * Lookup a sid and obtain the domain sid and account name.
72011337SWilliam.Krier@Sun.COM * This is a wrapper for the various lookup sid RPCs.
72111337SWilliam.Krier@Sun.COM */
72211337SWilliam.Krier@Sun.COM uint32_t
lsar_lookup_sids(mlsvc_handle_t * lsa_handle,smb_sid_t * sid,smb_account_t * account)72311337SWilliam.Krier@Sun.COM lsar_lookup_sids(mlsvc_handle_t *lsa_handle, smb_sid_t *sid,
72411337SWilliam.Krier@Sun.COM smb_account_t *account)
72511337SWilliam.Krier@Sun.COM {
72611337SWilliam.Krier@Sun.COM char sidbuf[SMB_SID_STRSZ];
72711337SWilliam.Krier@Sun.COM uint32_t status;
72811337SWilliam.Krier@Sun.COM
72911337SWilliam.Krier@Sun.COM if (lsa_handle == NULL || sid == NULL || account == NULL)
73011337SWilliam.Krier@Sun.COM return (NT_STATUS_INVALID_PARAMETER);
73111337SWilliam.Krier@Sun.COM
73211337SWilliam.Krier@Sun.COM bzero(account, sizeof (smb_account_t));
73311337SWilliam.Krier@Sun.COM bzero(sidbuf, SMB_SID_STRSZ);
73411337SWilliam.Krier@Sun.COM smb_sid_tostr(sid, sidbuf);
73511337SWilliam.Krier@Sun.COM smb_tracef("%s", sidbuf);
73611337SWilliam.Krier@Sun.COM
73711337SWilliam.Krier@Sun.COM if (ndr_rpc_server_os(lsa_handle) == NATIVE_OS_WIN2000)
73811337SWilliam.Krier@Sun.COM status = lsar_lookup_sids2(lsa_handle, (lsa_sid_t *)sid,
73911337SWilliam.Krier@Sun.COM account);
74011337SWilliam.Krier@Sun.COM else
74111337SWilliam.Krier@Sun.COM status = lsar_lookup_sids1(lsa_handle, (lsa_sid_t *)sid,
74211337SWilliam.Krier@Sun.COM account);
74311337SWilliam.Krier@Sun.COM
74411337SWilliam.Krier@Sun.COM if (status == NT_STATUS_SUCCESS) {
74511337SWilliam.Krier@Sun.COM if (!smb_account_validate(account)) {
74611337SWilliam.Krier@Sun.COM smb_account_free(account);
74711337SWilliam.Krier@Sun.COM status = NT_STATUS_NO_MEMORY;
74811337SWilliam.Krier@Sun.COM } else {
74911337SWilliam.Krier@Sun.COM smb_account_trace(account);
75011337SWilliam.Krier@Sun.COM }
75111337SWilliam.Krier@Sun.COM }
75211337SWilliam.Krier@Sun.COM
75311337SWilliam.Krier@Sun.COM return (status);
75411337SWilliam.Krier@Sun.COM }
75511337SWilliam.Krier@Sun.COM
75611337SWilliam.Krier@Sun.COM /*
75711337SWilliam.Krier@Sun.COM * lsar_lookup_sids1
75811337SWilliam.Krier@Sun.COM */
75911337SWilliam.Krier@Sun.COM static uint32_t
lsar_lookup_sids1(mlsvc_handle_t * lsa_handle,lsa_sid_t * sid,smb_account_t * account)76011337SWilliam.Krier@Sun.COM lsar_lookup_sids1(mlsvc_handle_t *lsa_handle, lsa_sid_t *sid,
76111337SWilliam.Krier@Sun.COM smb_account_t *account)
76211337SWilliam.Krier@Sun.COM {
76311337SWilliam.Krier@Sun.COM struct mslsa_LookupSids arg;
76411337SWilliam.Krier@Sun.COM struct mslsa_lup_sid_entry sid_entry;
76511337SWilliam.Krier@Sun.COM struct mslsa_name_entry *name_entry;
76611337SWilliam.Krier@Sun.COM struct mslsa_domain_entry *domain_entry;
76711337SWilliam.Krier@Sun.COM uint32_t status = NT_STATUS_SUCCESS;
76811337SWilliam.Krier@Sun.COM char *name;
76911337SWilliam.Krier@Sun.COM int opnum = LSARPC_OPNUM_LookupSids;
77011337SWilliam.Krier@Sun.COM
77111337SWilliam.Krier@Sun.COM bzero(&arg, sizeof (struct mslsa_LookupSids));
77211337SWilliam.Krier@Sun.COM (void) memcpy(&arg.handle, lsa_handle, sizeof (mslsa_handle_t));
77311337SWilliam.Krier@Sun.COM arg.lookup_level = LSA_LOOKUP_WKSTA;
77411337SWilliam.Krier@Sun.COM
77511337SWilliam.Krier@Sun.COM sid_entry.psid = sid;
77611337SWilliam.Krier@Sun.COM arg.lup_sid_table.n_entry = 1;
77711337SWilliam.Krier@Sun.COM arg.lup_sid_table.entries = &sid_entry;
77811337SWilliam.Krier@Sun.COM
77911337SWilliam.Krier@Sun.COM if (ndr_rpc_call(lsa_handle, opnum, &arg) != 0) {
78011337SWilliam.Krier@Sun.COM ndr_rpc_release(lsa_handle);
78111337SWilliam.Krier@Sun.COM return (NT_STATUS_INVALID_PARAMETER);
78211337SWilliam.Krier@Sun.COM }
78311337SWilliam.Krier@Sun.COM
78411337SWilliam.Krier@Sun.COM if (arg.status != NT_STATUS_SUCCESS) {
78511337SWilliam.Krier@Sun.COM ndr_rpc_status(lsa_handle, opnum, arg.status);
78611337SWilliam.Krier@Sun.COM ndr_rpc_release(lsa_handle);
78711337SWilliam.Krier@Sun.COM return (NT_SC_VALUE(arg.status));
78811337SWilliam.Krier@Sun.COM }
78911337SWilliam.Krier@Sun.COM
79011337SWilliam.Krier@Sun.COM if (arg.mapped_count == 0) {
79111337SWilliam.Krier@Sun.COM ndr_rpc_release(lsa_handle);
79211337SWilliam.Krier@Sun.COM return (NT_STATUS_NONE_MAPPED);
79311337SWilliam.Krier@Sun.COM }
79411337SWilliam.Krier@Sun.COM
79511337SWilliam.Krier@Sun.COM name_entry = &arg.name_table.entries[0];
79611337SWilliam.Krier@Sun.COM if (name_entry->domain_ix != 0) {
79711337SWilliam.Krier@Sun.COM ndr_rpc_release(lsa_handle);
79811337SWilliam.Krier@Sun.COM return (NT_STATUS_NONE_MAPPED);
79911337SWilliam.Krier@Sun.COM }
80011337SWilliam.Krier@Sun.COM
80111337SWilliam.Krier@Sun.COM name = (char *)name_entry->name.str;
80211337SWilliam.Krier@Sun.COM account->a_name = (name) ? strdup(name) : strdup("");
80311337SWilliam.Krier@Sun.COM account->a_type = name_entry->sid_name_use;
80411337SWilliam.Krier@Sun.COM account->a_sid = smb_sid_dup((smb_sid_t *)sid);
80511337SWilliam.Krier@Sun.COM (void) smb_sid_getrid(account->a_sid, &account->a_rid);
80611337SWilliam.Krier@Sun.COM
80711337SWilliam.Krier@Sun.COM domain_entry = &arg.domain_table->entries[0];
80811337SWilliam.Krier@Sun.COM if ((name = (char *)domain_entry->domain_name.str) != NULL)
80911337SWilliam.Krier@Sun.COM account->a_domain = strdup(name);
81011337SWilliam.Krier@Sun.COM account->a_domsid = smb_sid_dup((smb_sid_t *)domain_entry->domain_sid);
81111337SWilliam.Krier@Sun.COM
81211337SWilliam.Krier@Sun.COM ndr_rpc_release(lsa_handle);
81311337SWilliam.Krier@Sun.COM return (status);
81411337SWilliam.Krier@Sun.COM }
81511337SWilliam.Krier@Sun.COM
81611337SWilliam.Krier@Sun.COM /*
81711337SWilliam.Krier@Sun.COM * lsar_lookup_sids2
81811337SWilliam.Krier@Sun.COM */
81911337SWilliam.Krier@Sun.COM static uint32_t
lsar_lookup_sids2(mlsvc_handle_t * lsa_handle,lsa_sid_t * sid,smb_account_t * account)82011337SWilliam.Krier@Sun.COM lsar_lookup_sids2(mlsvc_handle_t *lsa_handle, lsa_sid_t *sid,
82111337SWilliam.Krier@Sun.COM smb_account_t *account)
82211337SWilliam.Krier@Sun.COM {
82311337SWilliam.Krier@Sun.COM struct lsar_lookup_sids2 arg;
82411337SWilliam.Krier@Sun.COM struct lsar_name_entry2 *name_entry;
82511337SWilliam.Krier@Sun.COM struct mslsa_lup_sid_entry sid_entry;
82611337SWilliam.Krier@Sun.COM struct mslsa_domain_entry *domain_entry;
82711337SWilliam.Krier@Sun.COM uint32_t status = NT_STATUS_SUCCESS;
82811337SWilliam.Krier@Sun.COM char *name;
82911337SWilliam.Krier@Sun.COM int opnum = LSARPC_OPNUM_LookupSids2;
83011337SWilliam.Krier@Sun.COM
83111337SWilliam.Krier@Sun.COM bzero(&arg, sizeof (struct lsar_lookup_sids2));
83211337SWilliam.Krier@Sun.COM (void) memcpy(&arg.policy_handle, lsa_handle, sizeof (mslsa_handle_t));
83311337SWilliam.Krier@Sun.COM
83411337SWilliam.Krier@Sun.COM sid_entry.psid = sid;
83511337SWilliam.Krier@Sun.COM arg.lup_sid_table.n_entry = 1;
83611337SWilliam.Krier@Sun.COM arg.lup_sid_table.entries = &sid_entry;
83711337SWilliam.Krier@Sun.COM arg.lookup_level = LSA_LOOKUP_WKSTA;
83811337SWilliam.Krier@Sun.COM arg.client_revision = LSA_CLIENT_REVISION_AD;
83911337SWilliam.Krier@Sun.COM
84011337SWilliam.Krier@Sun.COM if (ndr_rpc_call(lsa_handle, opnum, &arg) != 0) {
84111337SWilliam.Krier@Sun.COM ndr_rpc_release(lsa_handle);
84211337SWilliam.Krier@Sun.COM return (NT_STATUS_INVALID_PARAMETER);
84311337SWilliam.Krier@Sun.COM }
84411337SWilliam.Krier@Sun.COM
84511337SWilliam.Krier@Sun.COM if (arg.status != NT_STATUS_SUCCESS) {
84611337SWilliam.Krier@Sun.COM ndr_rpc_status(lsa_handle, opnum, arg.status);
84711337SWilliam.Krier@Sun.COM ndr_rpc_release(lsa_handle);
84811337SWilliam.Krier@Sun.COM return (NT_SC_VALUE(arg.status));
84911337SWilliam.Krier@Sun.COM }
85011337SWilliam.Krier@Sun.COM
85111337SWilliam.Krier@Sun.COM if (arg.mapped_count == 0) {
85211337SWilliam.Krier@Sun.COM ndr_rpc_release(lsa_handle);
85311337SWilliam.Krier@Sun.COM return (NT_STATUS_NONE_MAPPED);
85411337SWilliam.Krier@Sun.COM }
85511337SWilliam.Krier@Sun.COM
85611337SWilliam.Krier@Sun.COM name_entry = &arg.name_table.entries[0];
85711337SWilliam.Krier@Sun.COM if (name_entry->domain_ix != 0) {
85811337SWilliam.Krier@Sun.COM ndr_rpc_release(lsa_handle);
85911337SWilliam.Krier@Sun.COM return (NT_STATUS_NONE_MAPPED);
86011337SWilliam.Krier@Sun.COM }
86111337SWilliam.Krier@Sun.COM
86211337SWilliam.Krier@Sun.COM name = (char *)name_entry->name.str;
86311337SWilliam.Krier@Sun.COM account->a_name = (name) ? strdup(name) : strdup("");
86411337SWilliam.Krier@Sun.COM account->a_type = name_entry->sid_name_use;
86511337SWilliam.Krier@Sun.COM account->a_sid = smb_sid_dup((smb_sid_t *)sid);
86611337SWilliam.Krier@Sun.COM (void) smb_sid_getrid(account->a_sid, &account->a_rid);
86711337SWilliam.Krier@Sun.COM
86811337SWilliam.Krier@Sun.COM domain_entry = &arg.domain_table->entries[0];
86911337SWilliam.Krier@Sun.COM if ((name = (char *)domain_entry->domain_name.str) != NULL)
87011337SWilliam.Krier@Sun.COM account->a_domain = strdup(name);
87111337SWilliam.Krier@Sun.COM account->a_domsid = smb_sid_dup((smb_sid_t *)domain_entry->domain_sid);
87211337SWilliam.Krier@Sun.COM
87311337SWilliam.Krier@Sun.COM ndr_rpc_release(lsa_handle);
87411337SWilliam.Krier@Sun.COM return (status);
87511337SWilliam.Krier@Sun.COM }
87611337SWilliam.Krier@Sun.COM
87711337SWilliam.Krier@Sun.COM /*
87811337SWilliam.Krier@Sun.COM * lsar_lookup_sids3
87911337SWilliam.Krier@Sun.COM *
88011337SWilliam.Krier@Sun.COM * This function is only valid if the remote RPC server is a domain
88111337SWilliam.Krier@Sun.COM * controller and requires the security extensions defined in MS-RPCE.
88211337SWilliam.Krier@Sun.COM *
88311337SWilliam.Krier@Sun.COM * Domain controllers will return RPC_NT_PROTSEQ_NOT_SUPPORTED here
88411337SWilliam.Krier@Sun.COM * because we don't support the RPC_C_AUTHN_NETLOGON security provider.
88511337SWilliam.Krier@Sun.COM * Non-domain controllers will return NT_STATUS_INVALID_SERVER_STATE.
88611337SWilliam.Krier@Sun.COM */
88711337SWilliam.Krier@Sun.COM static uint32_t /*LINTED E_STATIC_UNUSED*/
lsar_lookup_sids3(mlsvc_handle_t * lsa_handle,lsa_sid_t * sid,smb_account_t * account)88811337SWilliam.Krier@Sun.COM lsar_lookup_sids3(mlsvc_handle_t *lsa_handle, lsa_sid_t *sid,
88911337SWilliam.Krier@Sun.COM smb_account_t *account)
89011337SWilliam.Krier@Sun.COM {
89111337SWilliam.Krier@Sun.COM struct lsar_lookup_sids3 arg;
89211337SWilliam.Krier@Sun.COM lsar_translated_name_ex_t *name_entry;
89311337SWilliam.Krier@Sun.COM struct mslsa_lup_sid_entry sid_entry;
89411337SWilliam.Krier@Sun.COM struct mslsa_domain_entry *domain_entry;
89511337SWilliam.Krier@Sun.COM uint32_t status = NT_STATUS_SUCCESS;
89611337SWilliam.Krier@Sun.COM char *name;
89711337SWilliam.Krier@Sun.COM int opnum = LSARPC_OPNUM_LookupSids3;
89811337SWilliam.Krier@Sun.COM
89911337SWilliam.Krier@Sun.COM bzero(&arg, sizeof (struct lsar_lookup_sids3));
90011337SWilliam.Krier@Sun.COM
90111337SWilliam.Krier@Sun.COM sid_entry.psid = sid;
90211337SWilliam.Krier@Sun.COM arg.lup_sid_table.n_entry = 1;
90311337SWilliam.Krier@Sun.COM arg.lup_sid_table.entries = &sid_entry;
90411337SWilliam.Krier@Sun.COM arg.lookup_level = LSA_LOOKUP_WKSTA;
90511337SWilliam.Krier@Sun.COM arg.client_revision = LSA_CLIENT_REVISION_AD;
90611337SWilliam.Krier@Sun.COM
90711337SWilliam.Krier@Sun.COM if (ndr_rpc_call(lsa_handle, opnum, &arg) != 0) {
90811337SWilliam.Krier@Sun.COM ndr_rpc_release(lsa_handle);
90911337SWilliam.Krier@Sun.COM return (NT_STATUS_INVALID_PARAMETER);
91011337SWilliam.Krier@Sun.COM }
91111337SWilliam.Krier@Sun.COM
91211337SWilliam.Krier@Sun.COM if (arg.status != NT_STATUS_SUCCESS) {
91311337SWilliam.Krier@Sun.COM ndr_rpc_status(lsa_handle, opnum, arg.status);
91411337SWilliam.Krier@Sun.COM ndr_rpc_release(lsa_handle);
91511337SWilliam.Krier@Sun.COM if (arg.status == RPC_NT_PROTSEQ_NOT_SUPPORTED ||
91611337SWilliam.Krier@Sun.COM arg.status == NT_STATUS_INVALID_SERVER_STATE)
91711337SWilliam.Krier@Sun.COM return (NT_STATUS_INVALID_PARAMETER);
91811337SWilliam.Krier@Sun.COM return (NT_SC_VALUE(arg.status));
91911337SWilliam.Krier@Sun.COM }
92011337SWilliam.Krier@Sun.COM
92111337SWilliam.Krier@Sun.COM if (arg.mapped_count == 0) {
92211337SWilliam.Krier@Sun.COM ndr_rpc_release(lsa_handle);
92311337SWilliam.Krier@Sun.COM return (NT_STATUS_NONE_MAPPED);
92411337SWilliam.Krier@Sun.COM }
92511337SWilliam.Krier@Sun.COM
92611337SWilliam.Krier@Sun.COM name_entry = &arg.name_table.entries[0];
92711337SWilliam.Krier@Sun.COM if (name_entry->domain_ix != 0) {
92811337SWilliam.Krier@Sun.COM ndr_rpc_release(lsa_handle);
92911337SWilliam.Krier@Sun.COM return (NT_STATUS_NONE_MAPPED);
93011337SWilliam.Krier@Sun.COM }
93111337SWilliam.Krier@Sun.COM
93211337SWilliam.Krier@Sun.COM name = (char *)name_entry->name.str;
93311337SWilliam.Krier@Sun.COM account->a_name = (name) ? strdup(name) : strdup("");
93411337SWilliam.Krier@Sun.COM account->a_type = name_entry->sid_name_use;
93511337SWilliam.Krier@Sun.COM account->a_sid = smb_sid_dup((smb_sid_t *)sid);
93611337SWilliam.Krier@Sun.COM (void) smb_sid_getrid(account->a_sid, &account->a_rid);
93711337SWilliam.Krier@Sun.COM
93811337SWilliam.Krier@Sun.COM domain_entry = &arg.domain_table->entries[0];
93911337SWilliam.Krier@Sun.COM if ((name = (char *)domain_entry->domain_name.str) != NULL)
94011337SWilliam.Krier@Sun.COM account->a_domain = strdup(name);
94111337SWilliam.Krier@Sun.COM account->a_domsid = smb_sid_dup((smb_sid_t *)domain_entry->domain_sid);
94211337SWilliam.Krier@Sun.COM
94311337SWilliam.Krier@Sun.COM ndr_rpc_release(lsa_handle);
94411337SWilliam.Krier@Sun.COM return (status);
94511337SWilliam.Krier@Sun.COM }
94611337SWilliam.Krier@Sun.COM
94711337SWilliam.Krier@Sun.COM /*
94811337SWilliam.Krier@Sun.COM * lsar_enum_accounts
94911337SWilliam.Krier@Sun.COM *
95011337SWilliam.Krier@Sun.COM * Enumerate the list of accounts (i.e. SIDs). Use the handle returned
95111337SWilliam.Krier@Sun.COM * from lsa_open_policy2. The enum_context is used to support multiple
95211337SWilliam.Krier@Sun.COM * calls to this enumeration function. It should be set to 0 on the
95311337SWilliam.Krier@Sun.COM * first call. It will be updated by the domain controller and should
95411337SWilliam.Krier@Sun.COM * simply be passed unchanged to subsequent calls until there are no
95511337SWilliam.Krier@Sun.COM * more accounts. A warning status of 0x1A indicates that no more data
95611337SWilliam.Krier@Sun.COM * is available. The list of accounts will be returned in accounts.
95711337SWilliam.Krier@Sun.COM * This list is dynamically allocated using malloc, it should be freed
95811337SWilliam.Krier@Sun.COM * by the caller when it is no longer required.
95911337SWilliam.Krier@Sun.COM */
96011337SWilliam.Krier@Sun.COM int
lsar_enum_accounts(mlsvc_handle_t * lsa_handle,DWORD * enum_context,struct mslsa_EnumAccountBuf * accounts)96111337SWilliam.Krier@Sun.COM lsar_enum_accounts(mlsvc_handle_t *lsa_handle, DWORD *enum_context,
96211337SWilliam.Krier@Sun.COM struct mslsa_EnumAccountBuf *accounts)
96311337SWilliam.Krier@Sun.COM {
96411337SWilliam.Krier@Sun.COM struct mslsa_EnumerateAccounts arg;
96511337SWilliam.Krier@Sun.COM struct mslsa_AccountInfo *info;
96611337SWilliam.Krier@Sun.COM int opnum;
96711337SWilliam.Krier@Sun.COM int rc;
96811337SWilliam.Krier@Sun.COM DWORD n_entries;
96911337SWilliam.Krier@Sun.COM DWORD i;
97011337SWilliam.Krier@Sun.COM int nbytes;
97111337SWilliam.Krier@Sun.COM
97211337SWilliam.Krier@Sun.COM if (lsa_handle == NULL || enum_context == NULL || accounts == NULL)
97311337SWilliam.Krier@Sun.COM return (-1);
97411337SWilliam.Krier@Sun.COM
97511337SWilliam.Krier@Sun.COM accounts->entries_read = 0;
97611337SWilliam.Krier@Sun.COM accounts->info = 0;
97711337SWilliam.Krier@Sun.COM
97811337SWilliam.Krier@Sun.COM opnum = LSARPC_OPNUM_EnumerateAccounts;
97911337SWilliam.Krier@Sun.COM
98011337SWilliam.Krier@Sun.COM bzero(&arg, sizeof (struct mslsa_EnumerateAccounts));
98111337SWilliam.Krier@Sun.COM (void) memcpy(&arg.handle, lsa_handle, sizeof (mslsa_handle_t));
98211337SWilliam.Krier@Sun.COM arg.enum_context = *enum_context;
98311337SWilliam.Krier@Sun.COM arg.max_length = MLSVC_MAX_RESPONSE_LEN;
98411337SWilliam.Krier@Sun.COM
98511337SWilliam.Krier@Sun.COM rc = ndr_rpc_call(lsa_handle, opnum, &arg);
98611337SWilliam.Krier@Sun.COM if (rc == 0) {
98711337SWilliam.Krier@Sun.COM if (arg.status != 0) {
988*12508Samw@Sun.COM if (arg.status == NT_STATUS_NO_MORE_ENTRIES) {
98911337SWilliam.Krier@Sun.COM *enum_context = arg.enum_context;
99011337SWilliam.Krier@Sun.COM } else {
99111337SWilliam.Krier@Sun.COM ndr_rpc_status(lsa_handle, opnum, arg.status);
99211337SWilliam.Krier@Sun.COM rc = -1;
99311337SWilliam.Krier@Sun.COM }
99411337SWilliam.Krier@Sun.COM } else if (arg.enum_buf->entries_read != 0) {
99511337SWilliam.Krier@Sun.COM n_entries = arg.enum_buf->entries_read;
99611337SWilliam.Krier@Sun.COM nbytes = n_entries * sizeof (struct mslsa_AccountInfo);
99711337SWilliam.Krier@Sun.COM
99811337SWilliam.Krier@Sun.COM if ((info = malloc(nbytes)) == NULL) {
99911337SWilliam.Krier@Sun.COM ndr_rpc_release(lsa_handle);
100011337SWilliam.Krier@Sun.COM return (-1);
100111337SWilliam.Krier@Sun.COM }
100211337SWilliam.Krier@Sun.COM
100311337SWilliam.Krier@Sun.COM for (i = 0; i < n_entries; ++i)
100411337SWilliam.Krier@Sun.COM info[i].sid = (lsa_sid_t *)smb_sid_dup(
100511337SWilliam.Krier@Sun.COM (smb_sid_t *)arg.enum_buf->info[i].sid);
100611337SWilliam.Krier@Sun.COM
100711337SWilliam.Krier@Sun.COM accounts->entries_read = n_entries;
100811337SWilliam.Krier@Sun.COM accounts->info = info;
100911337SWilliam.Krier@Sun.COM *enum_context = arg.enum_context;
101011337SWilliam.Krier@Sun.COM }
101111337SWilliam.Krier@Sun.COM }
101211337SWilliam.Krier@Sun.COM
101311337SWilliam.Krier@Sun.COM ndr_rpc_release(lsa_handle);
101411337SWilliam.Krier@Sun.COM return (rc);
101511337SWilliam.Krier@Sun.COM }
101611337SWilliam.Krier@Sun.COM
101711337SWilliam.Krier@Sun.COM /*
101811337SWilliam.Krier@Sun.COM * lsar_enum_trusted_domains
101911337SWilliam.Krier@Sun.COM *
102011337SWilliam.Krier@Sun.COM * Enumerate the list of trusted domains. Use the handle returned from
102111337SWilliam.Krier@Sun.COM * lsa_open_policy2. The enum_context is used to support multiple calls
102211337SWilliam.Krier@Sun.COM * to this enumeration function. It should be set to 0 on the first
102311337SWilliam.Krier@Sun.COM * call. It will be updated by the domain controller and should simply
102411337SWilliam.Krier@Sun.COM * be passed unchanged to subsequent calls until there are no more
102511337SWilliam.Krier@Sun.COM * domains.
102611337SWilliam.Krier@Sun.COM *
102711337SWilliam.Krier@Sun.COM * The trusted domains aren't actually returned here. They are added
102811337SWilliam.Krier@Sun.COM * to the NT domain database. After all of the trusted domains have
102911337SWilliam.Krier@Sun.COM * been discovered, the database can be interrogated to find all of
103011337SWilliam.Krier@Sun.COM * the trusted domains.
103111337SWilliam.Krier@Sun.COM */
103211337SWilliam.Krier@Sun.COM DWORD
lsar_enum_trusted_domains(mlsvc_handle_t * lsa_handle,DWORD * enum_context,smb_trusted_domains_t * list)103311337SWilliam.Krier@Sun.COM lsar_enum_trusted_domains(mlsvc_handle_t *lsa_handle, DWORD *enum_context,
103411337SWilliam.Krier@Sun.COM smb_trusted_domains_t *list)
103511337SWilliam.Krier@Sun.COM {
103611337SWilliam.Krier@Sun.COM struct mslsa_EnumTrustedDomain arg;
103711337SWilliam.Krier@Sun.COM int opnum;
103811337SWilliam.Krier@Sun.COM DWORD status;
103911337SWilliam.Krier@Sun.COM
104011337SWilliam.Krier@Sun.COM if (list == NULL)
104111337SWilliam.Krier@Sun.COM return (NT_STATUS_INVALID_PARAMETER);
104211337SWilliam.Krier@Sun.COM
104311337SWilliam.Krier@Sun.COM opnum = LSARPC_OPNUM_EnumTrustedDomain;
104411337SWilliam.Krier@Sun.COM
104511337SWilliam.Krier@Sun.COM bzero(list, sizeof (smb_trusted_domains_t));
104611337SWilliam.Krier@Sun.COM bzero(&arg, sizeof (struct mslsa_EnumTrustedDomain));
104711337SWilliam.Krier@Sun.COM (void) memcpy(&arg.handle, lsa_handle, sizeof (mslsa_handle_t));
104811337SWilliam.Krier@Sun.COM arg.enum_context = *enum_context;
104911337SWilliam.Krier@Sun.COM arg.max_length = MLSVC_MAX_RESPONSE_LEN;
105011337SWilliam.Krier@Sun.COM
105111337SWilliam.Krier@Sun.COM if (ndr_rpc_call(lsa_handle, opnum, &arg) != 0) {
105211337SWilliam.Krier@Sun.COM status = NT_STATUS_INVALID_PARAMETER;
105311337SWilliam.Krier@Sun.COM } else if (arg.status != 0) {
105411337SWilliam.Krier@Sun.COM *enum_context = arg.enum_context;
105511337SWilliam.Krier@Sun.COM status = NT_SC_VALUE(arg.status);
105611337SWilliam.Krier@Sun.COM
105711337SWilliam.Krier@Sun.COM /*
1058*12508Samw@Sun.COM * STATUS_NO_MORE_ENTRIES provides call
1059*12508Samw@Sun.COM * status but does not indicate an error.
106011337SWilliam.Krier@Sun.COM */
1061*12508Samw@Sun.COM if (status != NT_STATUS_NO_MORE_ENTRIES)
106211337SWilliam.Krier@Sun.COM ndr_rpc_status(lsa_handle, opnum, arg.status);
106311337SWilliam.Krier@Sun.COM } else if (arg.enum_buf->entries_read == 0) {
106411337SWilliam.Krier@Sun.COM *enum_context = arg.enum_context;
106511337SWilliam.Krier@Sun.COM status = 0;
106611337SWilliam.Krier@Sun.COM } else {
106711337SWilliam.Krier@Sun.COM lsar_set_trusted_domains(arg.enum_buf, list);
106811337SWilliam.Krier@Sun.COM *enum_context = arg.enum_context;
106911337SWilliam.Krier@Sun.COM status = 0;
107011337SWilliam.Krier@Sun.COM }
107111337SWilliam.Krier@Sun.COM
107211337SWilliam.Krier@Sun.COM ndr_rpc_release(lsa_handle);
107311337SWilliam.Krier@Sun.COM return (status);
107411337SWilliam.Krier@Sun.COM }
107511337SWilliam.Krier@Sun.COM
107611337SWilliam.Krier@Sun.COM DWORD
lsar_enum_trusted_domains_ex(mlsvc_handle_t * lsa_handle,DWORD * enum_context,smb_trusted_domains_t * list)107711337SWilliam.Krier@Sun.COM lsar_enum_trusted_domains_ex(mlsvc_handle_t *lsa_handle, DWORD *enum_context,
107811337SWilliam.Krier@Sun.COM smb_trusted_domains_t *list)
107911337SWilliam.Krier@Sun.COM {
108011337SWilliam.Krier@Sun.COM struct mslsa_EnumTrustedDomainEx arg;
108111337SWilliam.Krier@Sun.COM int opnum;
108211337SWilliam.Krier@Sun.COM DWORD status;
108311337SWilliam.Krier@Sun.COM
108411337SWilliam.Krier@Sun.COM if (list == NULL)
108511337SWilliam.Krier@Sun.COM return (NT_STATUS_INVALID_PARAMETER);
108611337SWilliam.Krier@Sun.COM
108711337SWilliam.Krier@Sun.COM opnum = LSARPC_OPNUM_EnumTrustedDomainsEx;
108811337SWilliam.Krier@Sun.COM
108911337SWilliam.Krier@Sun.COM bzero(list, sizeof (smb_trusted_domains_t));
109011337SWilliam.Krier@Sun.COM bzero(&arg, sizeof (struct mslsa_EnumTrustedDomainEx));
109111337SWilliam.Krier@Sun.COM (void) memcpy(&arg.handle, lsa_handle, sizeof (mslsa_handle_t));
109211337SWilliam.Krier@Sun.COM arg.enum_context = *enum_context;
109311337SWilliam.Krier@Sun.COM arg.max_length = MLSVC_MAX_RESPONSE_LEN;
109411337SWilliam.Krier@Sun.COM
109511337SWilliam.Krier@Sun.COM if (ndr_rpc_call(lsa_handle, opnum, &arg) != 0) {
109611337SWilliam.Krier@Sun.COM status = NT_STATUS_INVALID_PARAMETER;
109711337SWilliam.Krier@Sun.COM } else if (arg.status != 0) {
109811337SWilliam.Krier@Sun.COM *enum_context = arg.enum_context;
109911337SWilliam.Krier@Sun.COM status = NT_SC_VALUE(arg.status);
110011337SWilliam.Krier@Sun.COM
110111337SWilliam.Krier@Sun.COM /*
1102*12508Samw@Sun.COM * STATUS_NO_MORE_ENTRIES provides call
1103*12508Samw@Sun.COM * status but does not indicate an error.
110411337SWilliam.Krier@Sun.COM */
1105*12508Samw@Sun.COM if (status != NT_STATUS_NO_MORE_ENTRIES)
110611337SWilliam.Krier@Sun.COM ndr_rpc_status(lsa_handle, opnum, arg.status);
110711337SWilliam.Krier@Sun.COM } else if (arg.enum_buf->entries_read == 0) {
110811337SWilliam.Krier@Sun.COM *enum_context = arg.enum_context;
110911337SWilliam.Krier@Sun.COM status = 0;
111011337SWilliam.Krier@Sun.COM } else {
111111337SWilliam.Krier@Sun.COM lsar_set_trusted_domains_ex(arg.enum_buf, list);
111211337SWilliam.Krier@Sun.COM *enum_context = arg.enum_context;
111311337SWilliam.Krier@Sun.COM status = 0;
111411337SWilliam.Krier@Sun.COM }
111511337SWilliam.Krier@Sun.COM
111611337SWilliam.Krier@Sun.COM ndr_rpc_release(lsa_handle);
111711337SWilliam.Krier@Sun.COM return (status);
111811337SWilliam.Krier@Sun.COM }
111911337SWilliam.Krier@Sun.COM
112011337SWilliam.Krier@Sun.COM /*
112111337SWilliam.Krier@Sun.COM * lsar_enum_privs_account
112211337SWilliam.Krier@Sun.COM *
112311337SWilliam.Krier@Sun.COM * Privileges enum? Need an account handle.
112411337SWilliam.Krier@Sun.COM */
112511337SWilliam.Krier@Sun.COM /*ARGSUSED*/
112611337SWilliam.Krier@Sun.COM int
lsar_enum_privs_account(mlsvc_handle_t * account_handle,smb_account_t * account)112711337SWilliam.Krier@Sun.COM lsar_enum_privs_account(mlsvc_handle_t *account_handle, smb_account_t *account)
112811337SWilliam.Krier@Sun.COM {
112911337SWilliam.Krier@Sun.COM struct mslsa_EnumPrivsAccount arg;
113011337SWilliam.Krier@Sun.COM int opnum;
113111337SWilliam.Krier@Sun.COM int rc;
113211337SWilliam.Krier@Sun.COM
113311337SWilliam.Krier@Sun.COM opnum = LSARPC_OPNUM_EnumPrivsAccount;
113411337SWilliam.Krier@Sun.COM
113511337SWilliam.Krier@Sun.COM bzero(&arg, sizeof (struct mslsa_EnumPrivsAccount));
113611337SWilliam.Krier@Sun.COM (void) memcpy(&arg.account_handle, &account_handle->handle,
113711337SWilliam.Krier@Sun.COM sizeof (mslsa_handle_t));
113811337SWilliam.Krier@Sun.COM
113911337SWilliam.Krier@Sun.COM rc = ndr_rpc_call(account_handle, opnum, &arg);
114011337SWilliam.Krier@Sun.COM if ((rc == 0) && (arg.status != 0)) {
114111337SWilliam.Krier@Sun.COM ndr_rpc_status(account_handle, opnum, arg.status);
114211337SWilliam.Krier@Sun.COM rc = -1;
114311337SWilliam.Krier@Sun.COM }
114411337SWilliam.Krier@Sun.COM ndr_rpc_release(account_handle);
114511337SWilliam.Krier@Sun.COM return (rc);
114611337SWilliam.Krier@Sun.COM }
114711337SWilliam.Krier@Sun.COM
114811337SWilliam.Krier@Sun.COM /*
114911337SWilliam.Krier@Sun.COM * lsar_lookup_priv_value
115011337SWilliam.Krier@Sun.COM *
115111337SWilliam.Krier@Sun.COM * Map a privilege name to a local unique id (LUID). Privilege names
115211337SWilliam.Krier@Sun.COM * are consistent across the network. LUIDs are machine specific.
115311337SWilliam.Krier@Sun.COM * This function provides the means to map a privilege name to the
115411337SWilliam.Krier@Sun.COM * LUID used by a remote server to represent it. The handle here is
115511337SWilliam.Krier@Sun.COM * a policy handle.
115611337SWilliam.Krier@Sun.COM */
115711337SWilliam.Krier@Sun.COM int
lsar_lookup_priv_value(mlsvc_handle_t * lsa_handle,char * name,struct ms_luid * luid)115811337SWilliam.Krier@Sun.COM lsar_lookup_priv_value(mlsvc_handle_t *lsa_handle, char *name,
115911337SWilliam.Krier@Sun.COM struct ms_luid *luid)
116011337SWilliam.Krier@Sun.COM {
116111337SWilliam.Krier@Sun.COM struct mslsa_LookupPrivValue arg;
116211337SWilliam.Krier@Sun.COM int opnum;
116311337SWilliam.Krier@Sun.COM int rc;
116411337SWilliam.Krier@Sun.COM size_t length;
116511337SWilliam.Krier@Sun.COM
116611337SWilliam.Krier@Sun.COM if (lsa_handle == NULL || name == NULL || luid == NULL)
116711337SWilliam.Krier@Sun.COM return (-1);
116811337SWilliam.Krier@Sun.COM
116911337SWilliam.Krier@Sun.COM opnum = LSARPC_OPNUM_LookupPrivValue;
117011337SWilliam.Krier@Sun.COM
117111337SWilliam.Krier@Sun.COM bzero(&arg, sizeof (struct mslsa_LookupPrivValue));
117211337SWilliam.Krier@Sun.COM (void) memcpy(&arg.handle, lsa_handle, sizeof (mslsa_handle_t));
117311337SWilliam.Krier@Sun.COM
117411337SWilliam.Krier@Sun.COM length = smb_wcequiv_strlen(name);
117511337SWilliam.Krier@Sun.COM if (ndr_rpc_server_os(lsa_handle) == NATIVE_OS_WIN2000)
117611337SWilliam.Krier@Sun.COM length += sizeof (smb_wchar_t);
117711337SWilliam.Krier@Sun.COM
117811337SWilliam.Krier@Sun.COM arg.name.length = length;
117911337SWilliam.Krier@Sun.COM arg.name.allosize = length;
118011337SWilliam.Krier@Sun.COM arg.name.str = (unsigned char *)name;
118111337SWilliam.Krier@Sun.COM
118211337SWilliam.Krier@Sun.COM rc = ndr_rpc_call(lsa_handle, opnum, &arg);
118311337SWilliam.Krier@Sun.COM if (rc == 0) {
118411337SWilliam.Krier@Sun.COM if (arg.status != 0)
118511337SWilliam.Krier@Sun.COM rc = -1;
118611337SWilliam.Krier@Sun.COM else
118711337SWilliam.Krier@Sun.COM (void) memcpy(luid, &arg.luid, sizeof (struct ms_luid));
118811337SWilliam.Krier@Sun.COM }
118911337SWilliam.Krier@Sun.COM
119011337SWilliam.Krier@Sun.COM ndr_rpc_release(lsa_handle);
119111337SWilliam.Krier@Sun.COM return (rc);
119211337SWilliam.Krier@Sun.COM }
119311337SWilliam.Krier@Sun.COM
119411337SWilliam.Krier@Sun.COM /*
119511337SWilliam.Krier@Sun.COM * lsar_lookup_priv_name
119611337SWilliam.Krier@Sun.COM *
119711337SWilliam.Krier@Sun.COM * Map a local unique id (LUID) to a privilege name. Privilege names
119811337SWilliam.Krier@Sun.COM * are consistent across the network. LUIDs are machine specific.
119911337SWilliam.Krier@Sun.COM * This function the means to map the LUID used by a remote server to
120011337SWilliam.Krier@Sun.COM * the appropriate privilege name. The handle here is a policy handle.
120111337SWilliam.Krier@Sun.COM */
120211337SWilliam.Krier@Sun.COM int
lsar_lookup_priv_name(mlsvc_handle_t * lsa_handle,struct ms_luid * luid,char * name,int namelen)120311337SWilliam.Krier@Sun.COM lsar_lookup_priv_name(mlsvc_handle_t *lsa_handle, struct ms_luid *luid,
120411337SWilliam.Krier@Sun.COM char *name, int namelen)
120511337SWilliam.Krier@Sun.COM {
120611337SWilliam.Krier@Sun.COM struct mslsa_LookupPrivName arg;
120711337SWilliam.Krier@Sun.COM int opnum;
120811337SWilliam.Krier@Sun.COM int rc;
120911337SWilliam.Krier@Sun.COM
121011337SWilliam.Krier@Sun.COM if (lsa_handle == NULL || luid == NULL || name == NULL)
121111337SWilliam.Krier@Sun.COM return (-1);
121211337SWilliam.Krier@Sun.COM
121311337SWilliam.Krier@Sun.COM opnum = LSARPC_OPNUM_LookupPrivName;
121411337SWilliam.Krier@Sun.COM
121511337SWilliam.Krier@Sun.COM bzero(&arg, sizeof (struct mslsa_LookupPrivName));
121611337SWilliam.Krier@Sun.COM (void) memcpy(&arg.handle, lsa_handle, sizeof (mslsa_handle_t));
121711337SWilliam.Krier@Sun.COM (void) memcpy(&arg.luid, luid, sizeof (struct ms_luid));
121811337SWilliam.Krier@Sun.COM
121911337SWilliam.Krier@Sun.COM rc = ndr_rpc_call(lsa_handle, opnum, &arg);
122011337SWilliam.Krier@Sun.COM if (rc == 0) {
122111337SWilliam.Krier@Sun.COM if (arg.status != 0)
122211337SWilliam.Krier@Sun.COM rc = -1;
122311337SWilliam.Krier@Sun.COM else
122411337SWilliam.Krier@Sun.COM (void) strlcpy(name, (char const *)arg.name->str,
122511337SWilliam.Krier@Sun.COM namelen);
122611337SWilliam.Krier@Sun.COM }
122711337SWilliam.Krier@Sun.COM
122811337SWilliam.Krier@Sun.COM ndr_rpc_release(lsa_handle);
122911337SWilliam.Krier@Sun.COM return (rc);
123011337SWilliam.Krier@Sun.COM }
123111337SWilliam.Krier@Sun.COM
123211337SWilliam.Krier@Sun.COM /*
123311337SWilliam.Krier@Sun.COM * lsar_lookup_priv_display_name
123411337SWilliam.Krier@Sun.COM *
123511337SWilliam.Krier@Sun.COM * Map a privilege name to a privilege display name. The input handle
123611337SWilliam.Krier@Sun.COM * should be an LSA policy handle and the name would normally be one
123711337SWilliam.Krier@Sun.COM * of the privileges defined in smb_privilege.h
123811337SWilliam.Krier@Sun.COM *
123911337SWilliam.Krier@Sun.COM * There's something peculiar about the return status from NT servers,
124011337SWilliam.Krier@Sun.COM * it's not always present. So for now, I'm ignoring the status in the
124111337SWilliam.Krier@Sun.COM * RPC response.
124211337SWilliam.Krier@Sun.COM *
124311337SWilliam.Krier@Sun.COM * Returns NT status codes.
124411337SWilliam.Krier@Sun.COM */
124511337SWilliam.Krier@Sun.COM DWORD
lsar_lookup_priv_display_name(mlsvc_handle_t * lsa_handle,char * name,char * display_name,int display_len)124611337SWilliam.Krier@Sun.COM lsar_lookup_priv_display_name(mlsvc_handle_t *lsa_handle, char *name,
124711337SWilliam.Krier@Sun.COM char *display_name, int display_len)
124811337SWilliam.Krier@Sun.COM {
124911337SWilliam.Krier@Sun.COM struct mslsa_LookupPrivDisplayName arg;
125011337SWilliam.Krier@Sun.COM int opnum;
125111337SWilliam.Krier@Sun.COM size_t length;
125211337SWilliam.Krier@Sun.COM DWORD status;
125311337SWilliam.Krier@Sun.COM
125411337SWilliam.Krier@Sun.COM if (lsa_handle == NULL || name == NULL || display_name == NULL)
125511337SWilliam.Krier@Sun.COM return (NT_STATUS_INVALID_PARAMETER);
125611337SWilliam.Krier@Sun.COM
125711337SWilliam.Krier@Sun.COM opnum = LSARPC_OPNUM_LookupPrivDisplayName;
125811337SWilliam.Krier@Sun.COM
125911337SWilliam.Krier@Sun.COM bzero(&arg, sizeof (struct mslsa_LookupPrivDisplayName));
126011337SWilliam.Krier@Sun.COM (void) memcpy(&arg.handle, lsa_handle, sizeof (mslsa_handle_t));
126111337SWilliam.Krier@Sun.COM
126211337SWilliam.Krier@Sun.COM length = smb_wcequiv_strlen(name);
126311337SWilliam.Krier@Sun.COM arg.name.length = length;
126411337SWilliam.Krier@Sun.COM arg.name.allosize = length;
126511337SWilliam.Krier@Sun.COM arg.name.str = (unsigned char *)name;
126611337SWilliam.Krier@Sun.COM
126711337SWilliam.Krier@Sun.COM arg.client_language = MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US);
126811337SWilliam.Krier@Sun.COM arg.default_language = MAKELANGID(LANG_ENGLISH, SUBLANG_NEUTRAL);
126911337SWilliam.Krier@Sun.COM
127011337SWilliam.Krier@Sun.COM if (ndr_rpc_call(lsa_handle, opnum, &arg) != 0)
127111337SWilliam.Krier@Sun.COM status = NT_STATUS_INVALID_PARAMETER;
127211337SWilliam.Krier@Sun.COM #if 0
127311337SWilliam.Krier@Sun.COM else if (arg.status != 0)
127411337SWilliam.Krier@Sun.COM status = NT_SC_VALUE(arg.status);
127511337SWilliam.Krier@Sun.COM #endif
127611337SWilliam.Krier@Sun.COM else {
127711337SWilliam.Krier@Sun.COM (void) strlcpy(display_name,
127811337SWilliam.Krier@Sun.COM (char const *)arg.display_name->str, display_len);
127911337SWilliam.Krier@Sun.COM status = NT_STATUS_SUCCESS;
128011337SWilliam.Krier@Sun.COM }
128111337SWilliam.Krier@Sun.COM
128211337SWilliam.Krier@Sun.COM ndr_rpc_release(lsa_handle);
128311337SWilliam.Krier@Sun.COM return (status);
128411337SWilliam.Krier@Sun.COM }
128511337SWilliam.Krier@Sun.COM
128611337SWilliam.Krier@Sun.COM static void
lsar_set_trusted_domains_ex(struct mslsa_EnumTrustedDomainBufEx * enum_buf,smb_trusted_domains_t * list)128711337SWilliam.Krier@Sun.COM lsar_set_trusted_domains_ex(struct mslsa_EnumTrustedDomainBufEx *enum_buf,
128811337SWilliam.Krier@Sun.COM smb_trusted_domains_t *list)
128911337SWilliam.Krier@Sun.COM {
129011337SWilliam.Krier@Sun.COM char sidstr[SMB_SID_STRSZ];
129111337SWilliam.Krier@Sun.COM int i;
129211337SWilliam.Krier@Sun.COM
129311337SWilliam.Krier@Sun.COM if (list == NULL || enum_buf == NULL || enum_buf->entries_read == 0)
129411337SWilliam.Krier@Sun.COM return;
129511337SWilliam.Krier@Sun.COM
129611337SWilliam.Krier@Sun.COM list->td_num = 0;
129711337SWilliam.Krier@Sun.COM list->td_domains = calloc(enum_buf->entries_read,
129811337SWilliam.Krier@Sun.COM sizeof (smb_domain_t));
129911337SWilliam.Krier@Sun.COM
130011337SWilliam.Krier@Sun.COM if (list->td_domains == NULL)
130111337SWilliam.Krier@Sun.COM return;
130211337SWilliam.Krier@Sun.COM
130311337SWilliam.Krier@Sun.COM list->td_num = enum_buf->entries_read;
130411337SWilliam.Krier@Sun.COM for (i = 0; i < list->td_num; i++) {
130511337SWilliam.Krier@Sun.COM smb_sid_tostr((smb_sid_t *)enum_buf->info[i].sid, sidstr);
130611337SWilliam.Krier@Sun.COM smb_domain_set_trust_info(
130711337SWilliam.Krier@Sun.COM sidstr,
130811337SWilliam.Krier@Sun.COM (char *)enum_buf->info[i].nb_name.str,
130911337SWilliam.Krier@Sun.COM (char *)enum_buf->info[i].dns_name.str,
131011337SWilliam.Krier@Sun.COM enum_buf->info[i].trust_direction,
131111337SWilliam.Krier@Sun.COM enum_buf->info[i].trust_type,
131211337SWilliam.Krier@Sun.COM enum_buf->info[i].trust_attrs,
131311337SWilliam.Krier@Sun.COM &list->td_domains[i]);
131411337SWilliam.Krier@Sun.COM }
131511337SWilliam.Krier@Sun.COM }
131611337SWilliam.Krier@Sun.COM
131711337SWilliam.Krier@Sun.COM static void
lsar_set_trusted_domains(struct mslsa_EnumTrustedDomainBuf * enum_buf,smb_trusted_domains_t * list)131811337SWilliam.Krier@Sun.COM lsar_set_trusted_domains(struct mslsa_EnumTrustedDomainBuf *enum_buf,
131911337SWilliam.Krier@Sun.COM smb_trusted_domains_t *list)
132011337SWilliam.Krier@Sun.COM {
132111337SWilliam.Krier@Sun.COM char sidstr[SMB_SID_STRSZ];
132211337SWilliam.Krier@Sun.COM int i;
132311337SWilliam.Krier@Sun.COM
132411337SWilliam.Krier@Sun.COM if (list == NULL || enum_buf == NULL || enum_buf->entries_read == 0)
132511337SWilliam.Krier@Sun.COM return;
132611337SWilliam.Krier@Sun.COM
132711337SWilliam.Krier@Sun.COM list->td_num = 0;
132811337SWilliam.Krier@Sun.COM list->td_domains = calloc(enum_buf->entries_read,
132911337SWilliam.Krier@Sun.COM sizeof (smb_domain_t));
133011337SWilliam.Krier@Sun.COM
133111337SWilliam.Krier@Sun.COM if (list->td_domains == NULL)
133211337SWilliam.Krier@Sun.COM return;
133311337SWilliam.Krier@Sun.COM
133411337SWilliam.Krier@Sun.COM list->td_num = enum_buf->entries_read;
133511337SWilliam.Krier@Sun.COM for (i = 0; i < list->td_num; i++) {
133611337SWilliam.Krier@Sun.COM smb_sid_tostr((smb_sid_t *)enum_buf->info[i].sid, sidstr);
133711337SWilliam.Krier@Sun.COM smb_domain_set_trust_info(
133811337SWilliam.Krier@Sun.COM sidstr, (char *)enum_buf->info[i].name.str,
133911337SWilliam.Krier@Sun.COM "", 0, 0, 0, &list->td_domains[i]);
134011337SWilliam.Krier@Sun.COM }
134111337SWilliam.Krier@Sun.COM }
134211337SWilliam.Krier@Sun.COM
134311337SWilliam.Krier@Sun.COM static void
smb_account_trace(const smb_account_t * info)134411337SWilliam.Krier@Sun.COM smb_account_trace(const smb_account_t *info)
134511337SWilliam.Krier@Sun.COM {
134611337SWilliam.Krier@Sun.COM char sidbuf[SMB_SID_STRSZ];
134711337SWilliam.Krier@Sun.COM
134811337SWilliam.Krier@Sun.COM bzero(sidbuf, SMB_SID_STRSZ);
134911337SWilliam.Krier@Sun.COM smb_sid_tostr(info->a_sid, sidbuf);
135011337SWilliam.Krier@Sun.COM
135111337SWilliam.Krier@Sun.COM smb_tracef("%s %s %s %lu %s", info->a_domain, info->a_name,
135211337SWilliam.Krier@Sun.COM sidbuf, info->a_rid, smb_sid_type2str(info->a_type));
135311337SWilliam.Krier@Sun.COM }
1354