17f667e74Sjose borrego /*
27f667e74Sjose borrego * CDDL HEADER START
37f667e74Sjose borrego *
47f667e74Sjose borrego * The contents of this file are subject to the terms of the
57f667e74Sjose borrego * Common Development and Distribution License (the "License").
67f667e74Sjose borrego * You may not use this file except in compliance with the License.
77f667e74Sjose borrego *
87f667e74Sjose borrego * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97f667e74Sjose borrego * or http://www.opensolaris.org/os/licensing.
107f667e74Sjose borrego * See the License for the specific language governing permissions
117f667e74Sjose borrego * and limitations under the License.
127f667e74Sjose borrego *
137f667e74Sjose borrego * When distributing Covered Code, include this CDDL HEADER in each
147f667e74Sjose borrego * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157f667e74Sjose borrego * If applicable, add the following below this CDDL HEADER, with the
167f667e74Sjose borrego * fields enclosed by brackets "[]" replaced with your own identifying
177f667e74Sjose borrego * information: Portions Copyright [yyyy] [name of copyright owner]
187f667e74Sjose borrego *
197f667e74Sjose borrego * CDDL HEADER END
207f667e74Sjose borrego */
217f667e74Sjose borrego /*
229fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
237f667e74Sjose borrego * Use is subject to license terms.
24b819cea2SGordon Ross *
25*9242c919SMatt Barden * Copyright 2017 Nexenta Systems, Inc. All rights reserved.
2662f63298SVitaliy Gusev * Copyright 2018 RackTop Systems.
277f667e74Sjose borrego */
287f667e74Sjose borrego
297f667e74Sjose borrego #include <strings.h>
307f667e74Sjose borrego #include <smbsrv/libsmb.h>
317f667e74Sjose borrego
327f667e74Sjose borrego extern int smb_pwd_num(void);
339fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States extern int smb_lgrp_numbydomain(smb_domain_type_t, int *);
347f667e74Sjose borrego
357f667e74Sjose borrego static uint32_t smb_sam_lookup_user(char *, smb_sid_t **);
367f667e74Sjose borrego static uint32_t smb_sam_lookup_group(char *, smb_sid_t **);
377f667e74Sjose borrego
3829bd2886SAlan Wright /*
3929bd2886SAlan Wright * Local well-known accounts data structure table and prototypes
4029bd2886SAlan Wright */
4129bd2886SAlan Wright typedef struct smb_lwka {
4229bd2886SAlan Wright uint32_t lwka_rid;
4329bd2886SAlan Wright char *lwka_name;
4429bd2886SAlan Wright uint16_t lwka_type;
4529bd2886SAlan Wright } smb_lwka_t;
4629bd2886SAlan Wright
4729bd2886SAlan Wright static smb_lwka_t lwka_tbl[] = {
4829bd2886SAlan Wright { 500, "Administrator", SidTypeUser },
4929bd2886SAlan Wright { 501, "Guest", SidTypeUser },
5029bd2886SAlan Wright { 502, "KRBTGT", SidTypeUser },
5129bd2886SAlan Wright { 512, "Domain Admins", SidTypeGroup },
5229bd2886SAlan Wright { 513, "Domain Users", SidTypeGroup },
5329bd2886SAlan Wright { 514, "Domain Guests", SidTypeGroup },
5429bd2886SAlan Wright { 516, "Domain Controllers", SidTypeGroup },
5529bd2886SAlan Wright { 517, "Cert Publishers", SidTypeGroup },
5629bd2886SAlan Wright { 518, "Schema Admins", SidTypeGroup },
5729bd2886SAlan Wright { 519, "Enterprise Admins", SidTypeGroup },
5829bd2886SAlan Wright { 520, "Global Policy Creator Owners", SidTypeGroup },
5929bd2886SAlan Wright { 533, "RAS and IAS Servers", SidTypeGroup }
6029bd2886SAlan Wright };
6129bd2886SAlan Wright
6229bd2886SAlan Wright #define SMB_LWKA_NUM (sizeof (lwka_tbl)/sizeof (lwka_tbl[0]))
6329bd2886SAlan Wright
6429bd2886SAlan Wright static smb_lwka_t *smb_lwka_lookup_name(char *);
6529bd2886SAlan Wright static smb_lwka_t *smb_lwka_lookup_sid(smb_sid_t *);
6629bd2886SAlan Wright
677f667e74Sjose borrego /*
687f667e74Sjose borrego * Looks up the given name in local account databases:
697f667e74Sjose borrego *
707f667e74Sjose borrego * SMB Local users are looked up in /var/smb/smbpasswd
717f667e74Sjose borrego * SMB Local groups are looked up in /var/smb/smbgroup.db
727f667e74Sjose borrego *
737f667e74Sjose borrego * If the account is found, its information is populated
747f667e74Sjose borrego * in the passed smb_account_t structure. Caller must free
757f667e74Sjose borrego * allocated memories by calling smb_account_free() upon
767f667e74Sjose borrego * successful return.
777f667e74Sjose borrego *
787f667e74Sjose borrego * The type of account is specified by 'type', which can be user,
797f667e74Sjose borrego * alias (local group) or unknown. If the caller doesn't know
807f667e74Sjose borrego * whether the name is a user or group name then SidTypeUnknown
817f667e74Sjose borrego * should be passed.
827f667e74Sjose borrego *
837f667e74Sjose borrego * If a local user and group have the same name, the user will
847f667e74Sjose borrego * always be picked. Note that this situation cannot happen on
857f667e74Sjose borrego * Windows systems.
867f667e74Sjose borrego *
877f667e74Sjose borrego * If a SMB local user/group is found but it turns out that
887f667e74Sjose borrego * it'll be mapped to a domain user/group the lookup is considered
897f667e74Sjose borrego * failed and NT_STATUS_NONE_MAPPED is returned.
907f667e74Sjose borrego *
917f667e74Sjose borrego * Return status:
927f667e74Sjose borrego *
937f667e74Sjose borrego * NT_STATUS_NOT_FOUND This is not a local account
947f667e74Sjose borrego * NT_STATUS_NONE_MAPPED It's a local account but cannot be
9562f63298SVitaliy Gusev * translated.
967f667e74Sjose borrego * other error status codes.
977f667e74Sjose borrego */
987f667e74Sjose borrego uint32_t
smb_sam_lookup_name(char * domain,char * name,uint16_t type,smb_account_t * account)997f667e74Sjose borrego smb_sam_lookup_name(char *domain, char *name, uint16_t type,
1007f667e74Sjose borrego smb_account_t *account)
1017f667e74Sjose borrego {
102a0aa776eSAlan Wright smb_domain_t di;
1037f667e74Sjose borrego smb_sid_t *sid;
1047f667e74Sjose borrego uint32_t status;
10529bd2886SAlan Wright smb_lwka_t *lwka;
1067f667e74Sjose borrego
1077f667e74Sjose borrego bzero(account, sizeof (smb_account_t));
1087f667e74Sjose borrego
1097f667e74Sjose borrego if (domain != NULL) {
110a0aa776eSAlan Wright if (!smb_domain_lookup_name(domain, &di) ||
111a0aa776eSAlan Wright (di.di_type != SMB_DOMAIN_LOCAL))
1127f667e74Sjose borrego return (NT_STATUS_NOT_FOUND);
1137f667e74Sjose borrego
1147f667e74Sjose borrego /* Only Netbios hostname is accepted */
115bbf6f00cSJordan Brown if (smb_strcasecmp(domain, di.di_nbname, 0) != 0)
1167f667e74Sjose borrego return (NT_STATUS_NONE_MAPPED);
11729bd2886SAlan Wright } else {
118a0aa776eSAlan Wright if (!smb_domain_lookup_type(SMB_DOMAIN_LOCAL, &di))
11929bd2886SAlan Wright return (NT_STATUS_CANT_ACCESS_DOMAIN_INFO);
1207f667e74Sjose borrego }
1217f667e74Sjose borrego
122bbf6f00cSJordan Brown if (smb_strcasecmp(name, di.di_nbname, 0) == 0) {
12329bd2886SAlan Wright /* This is the local domain name */
12429bd2886SAlan Wright account->a_type = SidTypeDomain;
12529bd2886SAlan Wright account->a_name = strdup("");
12629bd2886SAlan Wright account->a_domain = strdup(di.di_nbname);
12729bd2886SAlan Wright account->a_sid = smb_sid_dup(di.di_binsid);
12829bd2886SAlan Wright account->a_domsid = smb_sid_dup(di.di_binsid);
12929bd2886SAlan Wright account->a_rid = (uint32_t)-1;
13029bd2886SAlan Wright
13129bd2886SAlan Wright if (!smb_account_validate(account)) {
13229bd2886SAlan Wright smb_account_free(account);
13329bd2886SAlan Wright return (NT_STATUS_NO_MEMORY);
13429bd2886SAlan Wright }
1357f667e74Sjose borrego
13629bd2886SAlan Wright return (NT_STATUS_SUCCESS);
13729bd2886SAlan Wright }
1387f667e74Sjose borrego
13929bd2886SAlan Wright if ((lwka = smb_lwka_lookup_name(name)) != NULL) {
14029bd2886SAlan Wright sid = smb_sid_splice(di.di_binsid, lwka->lwka_rid);
14129bd2886SAlan Wright type = lwka->lwka_type;
14229bd2886SAlan Wright } else {
14329bd2886SAlan Wright switch (type) {
14429bd2886SAlan Wright case SidTypeUser:
14529bd2886SAlan Wright status = smb_sam_lookup_user(name, &sid);
14629bd2886SAlan Wright if (status != NT_STATUS_SUCCESS)
14729bd2886SAlan Wright return (status);
1487f667e74Sjose borrego break;
1497f667e74Sjose borrego
15029bd2886SAlan Wright case SidTypeAlias:
15129bd2886SAlan Wright status = smb_sam_lookup_group(name, &sid);
15229bd2886SAlan Wright if (status != NT_STATUS_SUCCESS)
15329bd2886SAlan Wright return (status);
15429bd2886SAlan Wright break;
1557f667e74Sjose borrego
15629bd2886SAlan Wright case SidTypeUnknown:
15729bd2886SAlan Wright type = SidTypeUser;
15829bd2886SAlan Wright status = smb_sam_lookup_user(name, &sid);
15929bd2886SAlan Wright if (status == NT_STATUS_SUCCESS)
16029bd2886SAlan Wright break;
1617f667e74Sjose borrego
16229bd2886SAlan Wright if (status == NT_STATUS_NONE_MAPPED)
16329bd2886SAlan Wright return (status);
16429bd2886SAlan Wright
16529bd2886SAlan Wright type = SidTypeAlias;
16629bd2886SAlan Wright status = smb_sam_lookup_group(name, &sid);
16729bd2886SAlan Wright if (status != NT_STATUS_SUCCESS)
16829bd2886SAlan Wright return (status);
16929bd2886SAlan Wright break;
17029bd2886SAlan Wright
17129bd2886SAlan Wright default:
17229bd2886SAlan Wright return (NT_STATUS_INVALID_PARAMETER);
17329bd2886SAlan Wright }
1747f667e74Sjose borrego }
1757f667e74Sjose borrego
1767f667e74Sjose borrego account->a_name = strdup(name);
1777f667e74Sjose borrego account->a_sid = sid;
17829bd2886SAlan Wright account->a_domain = strdup(di.di_nbname);
1797f667e74Sjose borrego account->a_domsid = smb_sid_split(sid, &account->a_rid);
1807f667e74Sjose borrego account->a_type = type;
1817f667e74Sjose borrego
1827f667e74Sjose borrego if (!smb_account_validate(account)) {
1837f667e74Sjose borrego smb_account_free(account);
1847f667e74Sjose borrego return (NT_STATUS_NO_MEMORY);
1857f667e74Sjose borrego }
1867f667e74Sjose borrego
1877f667e74Sjose borrego return (NT_STATUS_SUCCESS);
1887f667e74Sjose borrego }
1897f667e74Sjose borrego
1907f667e74Sjose borrego /*
1917f667e74Sjose borrego * Looks up the given SID in local account databases:
1927f667e74Sjose borrego *
1937f667e74Sjose borrego * SMB Local users are looked up in /var/smb/smbpasswd
1947f667e74Sjose borrego * SMB Local groups are looked up in /var/smb/smbgroup.db
1957f667e74Sjose borrego *
1967f667e74Sjose borrego * If the account is found, its information is populated
1977f667e74Sjose borrego * in the passed smb_account_t structure. Caller must free
1987f667e74Sjose borrego * allocated memories by calling smb_account_free() upon
1997f667e74Sjose borrego * successful return.
2007f667e74Sjose borrego *
2017f667e74Sjose borrego * Return status:
2027f667e74Sjose borrego *
2037f667e74Sjose borrego * NT_STATUS_NOT_FOUND This is not a local account
2047f667e74Sjose borrego * NT_STATUS_NONE_MAPPED It's a local account but cannot be
20562f63298SVitaliy Gusev * translated.
2067f667e74Sjose borrego * other error status codes.
2077f667e74Sjose borrego */
2087f667e74Sjose borrego uint32_t
smb_sam_lookup_sid(smb_sid_t * sid,smb_account_t * account)2097f667e74Sjose borrego smb_sam_lookup_sid(smb_sid_t *sid, smb_account_t *account)
2107f667e74Sjose borrego {
2117f667e74Sjose borrego char hostname[MAXHOSTNAMELEN];
2127f667e74Sjose borrego smb_passwd_t smbpw;
2137f667e74Sjose borrego smb_group_t grp;
21429bd2886SAlan Wright smb_lwka_t *lwka;
215a0aa776eSAlan Wright smb_domain_t di;
2167f667e74Sjose borrego uint32_t rid;
2177f667e74Sjose borrego uid_t id;
2187f667e74Sjose borrego int id_type;
2197f667e74Sjose borrego int rc;
2207f667e74Sjose borrego
2217f667e74Sjose borrego bzero(account, sizeof (smb_account_t));
2227f667e74Sjose borrego
223a0aa776eSAlan Wright if (!smb_domain_lookup_type(SMB_DOMAIN_LOCAL, &di))
22429bd2886SAlan Wright return (NT_STATUS_CANT_ACCESS_DOMAIN_INFO);
22529bd2886SAlan Wright
22629bd2886SAlan Wright if (smb_sid_cmp(sid, di.di_binsid)) {
22729bd2886SAlan Wright /* This is the local domain SID */
22829bd2886SAlan Wright account->a_type = SidTypeDomain;
22929bd2886SAlan Wright account->a_name = strdup("");
23029bd2886SAlan Wright account->a_domain = strdup(di.di_nbname);
23129bd2886SAlan Wright account->a_sid = smb_sid_dup(sid);
23229bd2886SAlan Wright account->a_domsid = smb_sid_dup(sid);
23329bd2886SAlan Wright account->a_rid = (uint32_t)-1;
23429bd2886SAlan Wright
23529bd2886SAlan Wright if (!smb_account_validate(account)) {
23629bd2886SAlan Wright smb_account_free(account);
23729bd2886SAlan Wright return (NT_STATUS_NO_MEMORY);
23829bd2886SAlan Wright }
23929bd2886SAlan Wright
24029bd2886SAlan Wright return (NT_STATUS_SUCCESS);
24129bd2886SAlan Wright }
24229bd2886SAlan Wright
24329bd2886SAlan Wright if (!smb_sid_indomain(di.di_binsid, sid)) {
24429bd2886SAlan Wright /* This is not a local SID */
2457f667e74Sjose borrego return (NT_STATUS_NOT_FOUND);
24629bd2886SAlan Wright }
2477f667e74Sjose borrego
24829bd2886SAlan Wright if ((lwka = smb_lwka_lookup_sid(sid)) != NULL) {
24929bd2886SAlan Wright account->a_type = lwka->lwka_type;
25029bd2886SAlan Wright account->a_name = strdup(lwka->lwka_name);
25129bd2886SAlan Wright } else {
25229bd2886SAlan Wright id_type = SMB_IDMAP_UNKNOWN;
25329bd2886SAlan Wright if (smb_idmap_getid(sid, &id, &id_type) != IDMAP_SUCCESS)
25429bd2886SAlan Wright return (NT_STATUS_NONE_MAPPED);
2557f667e74Sjose borrego
25629bd2886SAlan Wright switch (id_type) {
25729bd2886SAlan Wright case SMB_IDMAP_USER:
25829bd2886SAlan Wright account->a_type = SidTypeUser;
25929bd2886SAlan Wright if (smb_pwd_getpwuid(id, &smbpw) == NULL)
26029bd2886SAlan Wright return (NT_STATUS_NO_SUCH_USER);
2617f667e74Sjose borrego
26229bd2886SAlan Wright account->a_name = strdup(smbpw.pw_name);
263*9242c919SMatt Barden account->a_flags = smbpw.pw_flags;
26429bd2886SAlan Wright break;
2657f667e74Sjose borrego
26629bd2886SAlan Wright case SMB_IDMAP_GROUP:
26729bd2886SAlan Wright account->a_type = SidTypeAlias;
26829bd2886SAlan Wright (void) smb_sid_getrid(sid, &rid);
2699fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States rc = smb_lgrp_getbyrid(rid, SMB_DOMAIN_LOCAL, &grp);
27029bd2886SAlan Wright if (rc != SMB_LGRP_SUCCESS)
27129bd2886SAlan Wright return (NT_STATUS_NO_SUCH_ALIAS);
2727f667e74Sjose borrego
27329bd2886SAlan Wright account->a_name = strdup(grp.sg_name);
27429bd2886SAlan Wright smb_lgrp_free(&grp);
27529bd2886SAlan Wright break;
2767f667e74Sjose borrego
27729bd2886SAlan Wright default:
27829bd2886SAlan Wright return (NT_STATUS_NONE_MAPPED);
27929bd2886SAlan Wright }
2807f667e74Sjose borrego }
2817f667e74Sjose borrego
2827f667e74Sjose borrego if (smb_getnetbiosname(hostname, MAXHOSTNAMELEN) == 0)
2837f667e74Sjose borrego account->a_domain = strdup(hostname);
2847f667e74Sjose borrego account->a_sid = smb_sid_dup(sid);
2857f667e74Sjose borrego account->a_domsid = smb_sid_split(sid, &account->a_rid);
2867f667e74Sjose borrego
2877f667e74Sjose borrego if (!smb_account_validate(account)) {
2887f667e74Sjose borrego smb_account_free(account);
2897f667e74Sjose borrego return (NT_STATUS_NO_MEMORY);
2907f667e74Sjose borrego }
2917f667e74Sjose borrego
2927f667e74Sjose borrego return (NT_STATUS_SUCCESS);
2937f667e74Sjose borrego }
2947f667e74Sjose borrego
2957f667e74Sjose borrego /*
2967f667e74Sjose borrego * Returns number of SMB users, i.e. users who have entry
2977f667e74Sjose borrego * in /var/smb/smbpasswd
2987f667e74Sjose borrego */
2997f667e74Sjose borrego int
smb_sam_usr_cnt(void)3007f667e74Sjose borrego smb_sam_usr_cnt(void)
3017f667e74Sjose borrego {
3027f667e74Sjose borrego return (smb_pwd_num());
3037f667e74Sjose borrego }
3047f667e74Sjose borrego
3057f667e74Sjose borrego /*
30636a00406SGordon Ross * Updates a list of groups in which the given user is a member
30736a00406SGordon Ross * by adding any local (SAM) groups.
30836a00406SGordon Ross *
30936a00406SGordon Ross * We are a member of local groups where the local group
31036a00406SGordon Ross * contains either the user's primary SID, or any of their
31136a00406SGordon Ross * other SIDs such as from domain groups, SID history, etc.
31236a00406SGordon Ross * We can have indirect membership via domain groups.
3137f667e74Sjose borrego */
3147f667e74Sjose borrego uint32_t
smb_sam_usr_groups(smb_sid_t * user_sid,smb_ids_t * gids)3157f667e74Sjose borrego smb_sam_usr_groups(smb_sid_t *user_sid, smb_ids_t *gids)
3167f667e74Sjose borrego {
31736a00406SGordon Ross smb_ids_t new_gids;
31836a00406SGordon Ross smb_id_t *ids, *new_ids;
3197f667e74Sjose borrego smb_giter_t gi;
3207f667e74Sjose borrego smb_group_t lgrp;
32136a00406SGordon Ross int i, gcnt, total_cnt;
32236a00406SGordon Ross uint32_t ret;
32336a00406SGordon Ross boolean_t member;
3247f667e74Sjose borrego
32536a00406SGordon Ross /*
32636a00406SGordon Ross * First pass: count groups to be added (gcnt)
32736a00406SGordon Ross */
3287f667e74Sjose borrego gcnt = 0;
3297f667e74Sjose borrego if (smb_lgrp_iteropen(&gi) != SMB_LGRP_SUCCESS)
3307f667e74Sjose borrego return (NT_STATUS_INTERNAL_ERROR);
3317f667e74Sjose borrego
3327f667e74Sjose borrego while (smb_lgrp_iterate(&gi, &lgrp) == SMB_LGRP_SUCCESS) {
33336a00406SGordon Ross member = B_FALSE;
3347f667e74Sjose borrego if (smb_lgrp_is_member(&lgrp, user_sid))
33536a00406SGordon Ross member = B_TRUE;
33636a00406SGordon Ross else for (i = 0, ids = gids->i_ids;
33736a00406SGordon Ross i < gids->i_cnt; i++, ids++) {
33836a00406SGordon Ross if (smb_lgrp_is_member(&lgrp, ids->i_sid)) {
33936a00406SGordon Ross member = B_TRUE;
34036a00406SGordon Ross break;
34136a00406SGordon Ross }
34236a00406SGordon Ross }
34336a00406SGordon Ross /* Careful: only count lgrp once */
34436a00406SGordon Ross if (member)
3457f667e74Sjose borrego gcnt++;
3467f667e74Sjose borrego smb_lgrp_free(&lgrp);
3477f667e74Sjose borrego }
3487f667e74Sjose borrego smb_lgrp_iterclose(&gi);
3497f667e74Sjose borrego
3507f667e74Sjose borrego if (gcnt == 0)
3517f667e74Sjose borrego return (NT_STATUS_SUCCESS);
3527f667e74Sjose borrego
35336a00406SGordon Ross /*
35436a00406SGordon Ross * Second pass: add to groups list.
35536a00406SGordon Ross * Do not modify gcnt after here.
35636a00406SGordon Ross */
3577f667e74Sjose borrego if (smb_lgrp_iteropen(&gi) != SMB_LGRP_SUCCESS)
3587f667e74Sjose borrego return (NT_STATUS_INTERNAL_ERROR);
3597f667e74Sjose borrego
36036a00406SGordon Ross /*
36136a00406SGordon Ross * Expand the list (copy to a new, larger one)
36236a00406SGordon Ross * Note: were're copying pointers from the old
36336a00406SGordon Ross * array to the new (larger) array, and then
36436a00406SGordon Ross * adding new pointers after what we copied.
36536a00406SGordon Ross */
36636a00406SGordon Ross ret = 0;
36736a00406SGordon Ross new_gids.i_cnt = gids->i_cnt;
36836a00406SGordon Ross total_cnt = gids->i_cnt + gcnt;
36936a00406SGordon Ross new_gids.i_ids = malloc(total_cnt * sizeof (smb_id_t));
37036a00406SGordon Ross if (new_gids.i_ids == NULL) {
37136a00406SGordon Ross ret = NT_STATUS_NO_MEMORY;
37236a00406SGordon Ross goto out;
37336a00406SGordon Ross }
37436a00406SGordon Ross (void) memcpy(new_gids.i_ids, gids->i_ids,
37536a00406SGordon Ross gids->i_cnt * sizeof (smb_id_t));
37636a00406SGordon Ross new_ids = new_gids.i_ids + gids->i_cnt;
37736a00406SGordon Ross (void) memset(new_ids, 0, gcnt * sizeof (smb_id_t));
37836a00406SGordon Ross
37936a00406SGordon Ross /*
38036a00406SGordon Ross * Add group SIDs starting at the end of the
38136a00406SGordon Ross * previous list. (new_ids)
38236a00406SGordon Ross */
3837f667e74Sjose borrego while (smb_lgrp_iterate(&gi, &lgrp) == SMB_LGRP_SUCCESS) {
38436a00406SGordon Ross member = B_FALSE;
38536a00406SGordon Ross if (smb_lgrp_is_member(&lgrp, user_sid))
38636a00406SGordon Ross member = B_TRUE;
38736a00406SGordon Ross else for (i = 0, ids = gids->i_ids;
38836a00406SGordon Ross i < gids->i_cnt; i++, ids++) {
38936a00406SGordon Ross if (smb_lgrp_is_member(&lgrp, ids->i_sid)) {
39036a00406SGordon Ross member = B_TRUE;
39136a00406SGordon Ross break;
39236a00406SGordon Ross }
3937f667e74Sjose borrego }
39436a00406SGordon Ross if (member && (new_gids.i_cnt < (gids->i_cnt + gcnt))) {
39536a00406SGordon Ross new_ids->i_sid = smb_sid_dup(lgrp.sg_id.gs_sid);
39636a00406SGordon Ross if (new_ids->i_sid == NULL) {
3977f667e74Sjose borrego smb_lgrp_free(&lgrp);
39836a00406SGordon Ross ret = NT_STATUS_NO_MEMORY;
39936a00406SGordon Ross goto out;
4007f667e74Sjose borrego }
40136a00406SGordon Ross new_ids->i_attrs = lgrp.sg_attr;
40236a00406SGordon Ross new_ids++;
40336a00406SGordon Ross new_gids.i_cnt++;
4047f667e74Sjose borrego }
4057f667e74Sjose borrego smb_lgrp_free(&lgrp);
4067f667e74Sjose borrego }
40736a00406SGordon Ross
40836a00406SGordon Ross out:
4097f667e74Sjose borrego smb_lgrp_iterclose(&gi);
4107f667e74Sjose borrego
41136a00406SGordon Ross if (ret != 0) {
41236a00406SGordon Ross if (new_gids.i_ids != NULL) {
41336a00406SGordon Ross /*
41436a00406SGordon Ross * Free only the new sids we added.
41536a00406SGordon Ross * The old ones were copied ptrs.
41636a00406SGordon Ross */
41736a00406SGordon Ross ids = new_gids.i_ids + gids->i_cnt;
41836a00406SGordon Ross for (i = 0; i < gcnt; i++, ids++) {
41936a00406SGordon Ross smb_sid_free(ids->i_sid);
42036a00406SGordon Ross }
42136a00406SGordon Ross free(new_gids.i_ids);
42236a00406SGordon Ross }
42336a00406SGordon Ross return (ret);
42436a00406SGordon Ross }
42536a00406SGordon Ross
42636a00406SGordon Ross /*
42736a00406SGordon Ross * Success! Update passed gids and
42836a00406SGordon Ross * free the old array.
42936a00406SGordon Ross */
43036a00406SGordon Ross free(gids->i_ids);
43136a00406SGordon Ross *gids = new_gids;
43236a00406SGordon Ross
4337f667e74Sjose borrego return (NT_STATUS_SUCCESS);
4347f667e74Sjose borrego }
4357f667e74Sjose borrego
4367f667e74Sjose borrego /*
4377f667e74Sjose borrego * Returns the number of built-in or local groups stored
4387f667e74Sjose borrego * in /var/smb/smbgroup.db
4397f667e74Sjose borrego */
4407f667e74Sjose borrego int
smb_sam_grp_cnt(smb_domain_type_t dtype)441a0aa776eSAlan Wright smb_sam_grp_cnt(smb_domain_type_t dtype)
4427f667e74Sjose borrego {
4437f667e74Sjose borrego int grpcnt;
4447f667e74Sjose borrego int rc;
4457f667e74Sjose borrego
4467f667e74Sjose borrego switch (dtype) {
447a0aa776eSAlan Wright case SMB_DOMAIN_BUILTIN:
4489fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States rc = smb_lgrp_numbydomain(SMB_DOMAIN_BUILTIN, &grpcnt);
4497f667e74Sjose borrego break;
4507f667e74Sjose borrego
451a0aa776eSAlan Wright case SMB_DOMAIN_LOCAL:
4529fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States rc = smb_lgrp_numbydomain(SMB_DOMAIN_LOCAL, &grpcnt);
4537f667e74Sjose borrego break;
4547f667e74Sjose borrego
4557f667e74Sjose borrego default:
4567f667e74Sjose borrego rc = SMB_LGRP_INVALID_ARG;
4577f667e74Sjose borrego }
4587f667e74Sjose borrego
4597f667e74Sjose borrego return ((rc == SMB_LGRP_SUCCESS) ? grpcnt : 0);
4607f667e74Sjose borrego }
4617f667e74Sjose borrego
4627f667e74Sjose borrego /*
4637f667e74Sjose borrego * Determines whether the given SID is a member of the group
4647f667e74Sjose borrego * specified by gname.
4657f667e74Sjose borrego */
4667f667e74Sjose borrego boolean_t
smb_sam_grp_ismember(const char * gname,smb_sid_t * sid)4677f667e74Sjose borrego smb_sam_grp_ismember(const char *gname, smb_sid_t *sid)
4687f667e74Sjose borrego {
4697f667e74Sjose borrego smb_group_t grp;
4707f667e74Sjose borrego boolean_t ismember = B_FALSE;
4717f667e74Sjose borrego
4727f667e74Sjose borrego if (smb_lgrp_getbyname((char *)gname, &grp) == SMB_LGRP_SUCCESS) {
4737f667e74Sjose borrego ismember = smb_lgrp_is_member(&grp, sid);
4747f667e74Sjose borrego smb_lgrp_free(&grp);
4757f667e74Sjose borrego }
4767f667e74Sjose borrego
4777f667e74Sjose borrego return (ismember);
4787f667e74Sjose borrego }
4797f667e74Sjose borrego
4807f667e74Sjose borrego /*
4817f667e74Sjose borrego * Frees memories allocated for the passed account fields.
48262f63298SVitaliy Gusev * Initializes @account after all.
4837f667e74Sjose borrego */
4847f667e74Sjose borrego void
smb_account_free(smb_account_t * account)4857f667e74Sjose borrego smb_account_free(smb_account_t *account)
4867f667e74Sjose borrego {
4877f667e74Sjose borrego free(account->a_name);
4887f667e74Sjose borrego free(account->a_domain);
4897f667e74Sjose borrego smb_sid_free(account->a_sid);
4907f667e74Sjose borrego smb_sid_free(account->a_domsid);
49162f63298SVitaliy Gusev
49262f63298SVitaliy Gusev bzero(account, sizeof (smb_account_t));
4937f667e74Sjose borrego }
4947f667e74Sjose borrego
4957f667e74Sjose borrego /*
4967f667e74Sjose borrego * Validates the given account.
4977f667e74Sjose borrego */
4987f667e74Sjose borrego boolean_t
smb_account_validate(smb_account_t * account)4997f667e74Sjose borrego smb_account_validate(smb_account_t *account)
5007f667e74Sjose borrego {
5017f667e74Sjose borrego return ((account->a_name != NULL) && (account->a_sid != NULL) &&
5027f667e74Sjose borrego (account->a_domain != NULL) && (account->a_domsid != NULL));
5037f667e74Sjose borrego }
5047f667e74Sjose borrego
5057f667e74Sjose borrego /*
5067f667e74Sjose borrego * Lookup local SMB user account database (/var/smb/smbpasswd)
5077f667e74Sjose borrego * if there's a match query its SID from idmap service and make
5087f667e74Sjose borrego * sure the SID is a local SID.
5097f667e74Sjose borrego *
5107f667e74Sjose borrego * The memory for the returned SID must be freed by the caller.
5117f667e74Sjose borrego */
5127f667e74Sjose borrego static uint32_t
smb_sam_lookup_user(char * name,smb_sid_t ** sid)5137f667e74Sjose borrego smb_sam_lookup_user(char *name, smb_sid_t **sid)
5147f667e74Sjose borrego {
5157f667e74Sjose borrego smb_passwd_t smbpw;
5167f667e74Sjose borrego
5177f667e74Sjose borrego if (smb_pwd_getpwnam(name, &smbpw) == NULL)
5187f667e74Sjose borrego return (NT_STATUS_NO_SUCH_USER);
5197f667e74Sjose borrego
5207f667e74Sjose borrego if (smb_idmap_getsid(smbpw.pw_uid, SMB_IDMAP_USER, sid)
5217f667e74Sjose borrego != IDMAP_SUCCESS)
5227f667e74Sjose borrego return (NT_STATUS_NONE_MAPPED);
5237f667e74Sjose borrego
5247f667e74Sjose borrego if (!smb_sid_islocal(*sid)) {
5257f667e74Sjose borrego smb_sid_free(*sid);
5267f667e74Sjose borrego return (NT_STATUS_NONE_MAPPED);
5277f667e74Sjose borrego }
5287f667e74Sjose borrego
5297f667e74Sjose borrego return (NT_STATUS_SUCCESS);
5307f667e74Sjose borrego }
5317f667e74Sjose borrego
5327f667e74Sjose borrego /*
5337f667e74Sjose borrego * Lookup local SMB group account database (/var/smb/smbgroup.db)
5347f667e74Sjose borrego * The memory for the returned SID must be freed by the caller.
5357f667e74Sjose borrego */
5367f667e74Sjose borrego static uint32_t
smb_sam_lookup_group(char * name,smb_sid_t ** sid)5377f667e74Sjose borrego smb_sam_lookup_group(char *name, smb_sid_t **sid)
5387f667e74Sjose borrego {
5397f667e74Sjose borrego smb_group_t grp;
5407f667e74Sjose borrego
5417f667e74Sjose borrego if (smb_lgrp_getbyname(name, &grp) != SMB_LGRP_SUCCESS)
5427f667e74Sjose borrego return (NT_STATUS_NO_SUCH_ALIAS);
5437f667e74Sjose borrego
5447f667e74Sjose borrego *sid = smb_sid_dup(grp.sg_id.gs_sid);
5457f667e74Sjose borrego smb_lgrp_free(&grp);
5467f667e74Sjose borrego
5477f667e74Sjose borrego return ((*sid == NULL) ? NT_STATUS_NO_MEMORY : NT_STATUS_SUCCESS);
5487f667e74Sjose borrego }
54929bd2886SAlan Wright
55029bd2886SAlan Wright static smb_lwka_t *
smb_lwka_lookup_name(char * name)55129bd2886SAlan Wright smb_lwka_lookup_name(char *name)
55229bd2886SAlan Wright {
55329bd2886SAlan Wright int i;
55429bd2886SAlan Wright
55529bd2886SAlan Wright for (i = 0; i < SMB_LWKA_NUM; i++) {
556bbf6f00cSJordan Brown if (smb_strcasecmp(name, lwka_tbl[i].lwka_name, 0) == 0)
55729bd2886SAlan Wright return (&lwka_tbl[i]);
55829bd2886SAlan Wright }
55929bd2886SAlan Wright
56029bd2886SAlan Wright return (NULL);
56129bd2886SAlan Wright }
56229bd2886SAlan Wright
56329bd2886SAlan Wright static smb_lwka_t *
smb_lwka_lookup_sid(smb_sid_t * sid)56429bd2886SAlan Wright smb_lwka_lookup_sid(smb_sid_t *sid)
56529bd2886SAlan Wright {
56629bd2886SAlan Wright uint32_t rid;
56729bd2886SAlan Wright int i;
56829bd2886SAlan Wright
56929bd2886SAlan Wright (void) smb_sid_getrid(sid, &rid);
57029bd2886SAlan Wright if (rid > 999)
57129bd2886SAlan Wright return (NULL);
57229bd2886SAlan Wright
57329bd2886SAlan Wright for (i = 0; i < SMB_LWKA_NUM; i++) {
57429bd2886SAlan Wright if (rid == lwka_tbl[i].lwka_rid)
57529bd2886SAlan Wright return (&lwka_tbl[i]);
57629bd2886SAlan Wright }
57729bd2886SAlan Wright
57829bd2886SAlan Wright return (NULL);
57929bd2886SAlan Wright }
580b819cea2SGordon Ross
581b819cea2SGordon Ross /*
582b819cea2SGordon Ross * smb_sid_islocal
583b819cea2SGordon Ross *
584b819cea2SGordon Ross * Check a SID to see if it belongs to the local domain.
585b819cea2SGordon Ross */
586b819cea2SGordon Ross boolean_t
smb_sid_islocal(smb_sid_t * sid)587b819cea2SGordon Ross smb_sid_islocal(smb_sid_t *sid)
588b819cea2SGordon Ross {
589b819cea2SGordon Ross smb_domain_t di;
590b819cea2SGordon Ross boolean_t islocal = B_FALSE;
591b819cea2SGordon Ross
592b819cea2SGordon Ross if (smb_domain_lookup_type(SMB_DOMAIN_LOCAL, &di))
593b819cea2SGordon Ross islocal = smb_sid_indomain(di.di_binsid, sid);
594b819cea2SGordon Ross
595b819cea2SGordon Ross return (islocal);
596b819cea2SGordon Ross }
597b819cea2SGordon Ross
598b819cea2SGordon Ross void
smb_ids_free(smb_ids_t * ids)599b819cea2SGordon Ross smb_ids_free(smb_ids_t *ids)
600b819cea2SGordon Ross {
601b819cea2SGordon Ross smb_id_t *id;
602b819cea2SGordon Ross int i;
603b819cea2SGordon Ross
604b819cea2SGordon Ross if ((ids != NULL) && (ids->i_ids != NULL)) {
605b819cea2SGordon Ross id = ids->i_ids;
606b819cea2SGordon Ross for (i = 0; i < ids->i_cnt; i++, id++)
607b819cea2SGordon Ross smb_sid_free(id->i_sid);
608b819cea2SGordon Ross
609b819cea2SGordon Ross free(ids->i_ids);
610b819cea2SGordon Ross }
611b819cea2SGordon Ross }
612