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.
24*7206bf49SGordon Ross *
25*7206bf49SGordon Ross * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
267f667e74Sjose borrego */
277f667e74Sjose borrego
287f667e74Sjose borrego #include <strings.h>
297f667e74Sjose borrego #include <smbsrv/libsmb.h>
307f667e74Sjose borrego
317f667e74Sjose borrego extern int smb_pwd_num(void);
329fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States extern int smb_lgrp_numbydomain(smb_domain_type_t, int *);
337f667e74Sjose borrego
347f667e74Sjose borrego static uint32_t smb_sam_lookup_user(char *, smb_sid_t **);
357f667e74Sjose borrego static uint32_t smb_sam_lookup_group(char *, smb_sid_t **);
367f667e74Sjose borrego
377f667e74Sjose borrego /*
3829bd2886SAlan Wright * Local well-known accounts data structure table and prototypes
3929bd2886SAlan Wright */
4029bd2886SAlan Wright typedef struct smb_lwka {
4129bd2886SAlan Wright uint32_t lwka_rid;
4229bd2886SAlan Wright char *lwka_name;
4329bd2886SAlan Wright uint16_t lwka_type;
4429bd2886SAlan Wright } smb_lwka_t;
4529bd2886SAlan Wright
4629bd2886SAlan Wright static smb_lwka_t lwka_tbl[] = {
4729bd2886SAlan Wright { 500, "Administrator", SidTypeUser },
4829bd2886SAlan Wright { 501, "Guest", SidTypeUser },
4929bd2886SAlan Wright { 502, "KRBTGT", SidTypeUser },
5029bd2886SAlan Wright { 512, "Domain Admins", SidTypeGroup },
5129bd2886SAlan Wright { 513, "Domain Users", SidTypeGroup },
5229bd2886SAlan Wright { 514, "Domain Guests", SidTypeGroup },
5329bd2886SAlan Wright { 516, "Domain Controllers", SidTypeGroup },
5429bd2886SAlan Wright { 517, "Cert Publishers", SidTypeGroup },
5529bd2886SAlan Wright { 518, "Schema Admins", SidTypeGroup },
5629bd2886SAlan Wright { 519, "Enterprise Admins", SidTypeGroup },
5729bd2886SAlan Wright { 520, "Global Policy Creator Owners", SidTypeGroup },
5829bd2886SAlan Wright { 533, "RAS and IAS Servers", SidTypeGroup }
5929bd2886SAlan Wright };
6029bd2886SAlan Wright
6129bd2886SAlan Wright #define SMB_LWKA_NUM (sizeof (lwka_tbl)/sizeof (lwka_tbl[0]))
6229bd2886SAlan Wright
6329bd2886SAlan Wright static smb_lwka_t *smb_lwka_lookup_name(char *);
6429bd2886SAlan Wright static smb_lwka_t *smb_lwka_lookup_sid(smb_sid_t *);
6529bd2886SAlan Wright
6629bd2886SAlan Wright /*
677f667e74Sjose borrego * Looks up the given name in local account databases:
687f667e74Sjose borrego *
697f667e74Sjose borrego * SMB Local users are looked up in /var/smb/smbpasswd
707f667e74Sjose borrego * SMB Local groups are looked up in /var/smb/smbgroup.db
717f667e74Sjose borrego *
727f667e74Sjose borrego * If the account is found, its information is populated
737f667e74Sjose borrego * in the passed smb_account_t structure. Caller must free
747f667e74Sjose borrego * allocated memories by calling smb_account_free() upon
757f667e74Sjose borrego * successful return.
767f667e74Sjose borrego *
777f667e74Sjose borrego * The type of account is specified by 'type', which can be user,
787f667e74Sjose borrego * alias (local group) or unknown. If the caller doesn't know
797f667e74Sjose borrego * whether the name is a user or group name then SidTypeUnknown
807f667e74Sjose borrego * should be passed.
817f667e74Sjose borrego *
827f667e74Sjose borrego * If a local user and group have the same name, the user will
837f667e74Sjose borrego * always be picked. Note that this situation cannot happen on
847f667e74Sjose borrego * Windows systems.
857f667e74Sjose borrego *
867f667e74Sjose borrego * If a SMB local user/group is found but it turns out that
877f667e74Sjose borrego * it'll be mapped to a domain user/group the lookup is considered
887f667e74Sjose borrego * failed and NT_STATUS_NONE_MAPPED is returned.
897f667e74Sjose borrego *
907f667e74Sjose borrego * Return status:
917f667e74Sjose borrego *
927f667e74Sjose borrego * NT_STATUS_NOT_FOUND This is not a local account
937f667e74Sjose borrego * NT_STATUS_NONE_MAPPED It's a local account but cannot be
947f667e74Sjose borrego * translated.
957f667e74Sjose borrego * other error status codes.
967f667e74Sjose borrego */
977f667e74Sjose borrego uint32_t
smb_sam_lookup_name(char * domain,char * name,uint16_t type,smb_account_t * account)987f667e74Sjose borrego smb_sam_lookup_name(char *domain, char *name, uint16_t type,
997f667e74Sjose borrego smb_account_t *account)
1007f667e74Sjose borrego {
101a0aa776eSAlan Wright smb_domain_t di;
1027f667e74Sjose borrego smb_sid_t *sid;
1037f667e74Sjose borrego uint32_t status;
10429bd2886SAlan Wright smb_lwka_t *lwka;
1057f667e74Sjose borrego
1067f667e74Sjose borrego bzero(account, sizeof (smb_account_t));
1077f667e74Sjose borrego
1087f667e74Sjose borrego if (domain != NULL) {
109a0aa776eSAlan Wright if (!smb_domain_lookup_name(domain, &di) ||
110a0aa776eSAlan Wright (di.di_type != SMB_DOMAIN_LOCAL))
1117f667e74Sjose borrego return (NT_STATUS_NOT_FOUND);
1127f667e74Sjose borrego
1137f667e74Sjose borrego /* Only Netbios hostname is accepted */
114bbf6f00cSJordan Brown if (smb_strcasecmp(domain, di.di_nbname, 0) != 0)
1157f667e74Sjose borrego return (NT_STATUS_NONE_MAPPED);
11629bd2886SAlan Wright } else {
117a0aa776eSAlan Wright if (!smb_domain_lookup_type(SMB_DOMAIN_LOCAL, &di))
11829bd2886SAlan Wright return (NT_STATUS_CANT_ACCESS_DOMAIN_INFO);
1197f667e74Sjose borrego }
1207f667e74Sjose borrego
121bbf6f00cSJordan Brown if (smb_strcasecmp(name, di.di_nbname, 0) == 0) {
12229bd2886SAlan Wright /* This is the local domain name */
12329bd2886SAlan Wright account->a_type = SidTypeDomain;
12429bd2886SAlan Wright account->a_name = strdup("");
12529bd2886SAlan Wright account->a_domain = strdup(di.di_nbname);
12629bd2886SAlan Wright account->a_sid = smb_sid_dup(di.di_binsid);
12729bd2886SAlan Wright account->a_domsid = smb_sid_dup(di.di_binsid);
12829bd2886SAlan Wright account->a_rid = (uint32_t)-1;
12929bd2886SAlan Wright
13029bd2886SAlan Wright if (!smb_account_validate(account)) {
13129bd2886SAlan Wright smb_account_free(account);
13229bd2886SAlan Wright return (NT_STATUS_NO_MEMORY);
13329bd2886SAlan Wright }
13429bd2886SAlan Wright
13529bd2886SAlan Wright return (NT_STATUS_SUCCESS);
13629bd2886SAlan Wright }
13729bd2886SAlan Wright
13829bd2886SAlan Wright if ((lwka = smb_lwka_lookup_name(name)) != NULL) {
13929bd2886SAlan Wright sid = smb_sid_splice(di.di_binsid, lwka->lwka_rid);
14029bd2886SAlan Wright type = lwka->lwka_type;
14129bd2886SAlan Wright } else {
1427f667e74Sjose borrego switch (type) {
1437f667e74Sjose borrego case SidTypeUser:
1447f667e74Sjose borrego status = smb_sam_lookup_user(name, &sid);
1457f667e74Sjose borrego if (status != NT_STATUS_SUCCESS)
1467f667e74Sjose borrego return (status);
1477f667e74Sjose borrego break;
1487f667e74Sjose borrego
1497f667e74Sjose borrego case SidTypeAlias:
1507f667e74Sjose borrego status = smb_sam_lookup_group(name, &sid);
1517f667e74Sjose borrego if (status != NT_STATUS_SUCCESS)
1527f667e74Sjose borrego return (status);
1537f667e74Sjose borrego break;
1547f667e74Sjose borrego
1557f667e74Sjose borrego case SidTypeUnknown:
1567f667e74Sjose borrego type = SidTypeUser;
1577f667e74Sjose borrego status = smb_sam_lookup_user(name, &sid);
1587f667e74Sjose borrego if (status == NT_STATUS_SUCCESS)
1597f667e74Sjose borrego break;
1607f667e74Sjose borrego
1617f667e74Sjose borrego if (status == NT_STATUS_NONE_MAPPED)
1627f667e74Sjose borrego return (status);
1637f667e74Sjose borrego
1647f667e74Sjose borrego type = SidTypeAlias;
1657f667e74Sjose borrego status = smb_sam_lookup_group(name, &sid);
1667f667e74Sjose borrego if (status != NT_STATUS_SUCCESS)
1677f667e74Sjose borrego return (status);
1687f667e74Sjose borrego break;
1697f667e74Sjose borrego
1707f667e74Sjose borrego default:
1717f667e74Sjose borrego return (NT_STATUS_INVALID_PARAMETER);
1727f667e74Sjose borrego }
17329bd2886SAlan Wright }
1747f667e74Sjose borrego
1757f667e74Sjose borrego account->a_name = strdup(name);
1767f667e74Sjose borrego account->a_sid = sid;
17729bd2886SAlan Wright account->a_domain = strdup(di.di_nbname);
1787f667e74Sjose borrego account->a_domsid = smb_sid_split(sid, &account->a_rid);
1797f667e74Sjose borrego account->a_type = type;
1807f667e74Sjose borrego
1817f667e74Sjose borrego if (!smb_account_validate(account)) {
1827f667e74Sjose borrego smb_account_free(account);
1837f667e74Sjose borrego return (NT_STATUS_NO_MEMORY);
1847f667e74Sjose borrego }
1857f667e74Sjose borrego
1867f667e74Sjose borrego return (NT_STATUS_SUCCESS);
1877f667e74Sjose borrego }
1887f667e74Sjose borrego
1897f667e74Sjose borrego /*
1907f667e74Sjose borrego * Looks up the given SID in local account databases:
1917f667e74Sjose borrego *
1927f667e74Sjose borrego * SMB Local users are looked up in /var/smb/smbpasswd
1937f667e74Sjose borrego * SMB Local groups are looked up in /var/smb/smbgroup.db
1947f667e74Sjose borrego *
1957f667e74Sjose borrego * If the account is found, its information is populated
1967f667e74Sjose borrego * in the passed smb_account_t structure. Caller must free
1977f667e74Sjose borrego * allocated memories by calling smb_account_free() upon
1987f667e74Sjose borrego * successful return.
1997f667e74Sjose borrego *
2007f667e74Sjose borrego * Return status:
2017f667e74Sjose borrego *
2027f667e74Sjose borrego * NT_STATUS_NOT_FOUND This is not a local account
2037f667e74Sjose borrego * NT_STATUS_NONE_MAPPED It's a local account but cannot be
2047f667e74Sjose borrego * translated.
2057f667e74Sjose borrego * other error status codes.
2067f667e74Sjose borrego */
2077f667e74Sjose borrego uint32_t
smb_sam_lookup_sid(smb_sid_t * sid,smb_account_t * account)2087f667e74Sjose borrego smb_sam_lookup_sid(smb_sid_t *sid, smb_account_t *account)
2097f667e74Sjose borrego {
2107f667e74Sjose borrego char hostname[MAXHOSTNAMELEN];
2117f667e74Sjose borrego smb_passwd_t smbpw;
2127f667e74Sjose borrego smb_group_t grp;
21329bd2886SAlan Wright smb_lwka_t *lwka;
214a0aa776eSAlan Wright smb_domain_t di;
2157f667e74Sjose borrego uint32_t rid;
2167f667e74Sjose borrego uid_t id;
2177f667e74Sjose borrego int id_type;
2187f667e74Sjose borrego int rc;
2197f667e74Sjose borrego
2207f667e74Sjose borrego bzero(account, sizeof (smb_account_t));
2217f667e74Sjose borrego
222a0aa776eSAlan Wright if (!smb_domain_lookup_type(SMB_DOMAIN_LOCAL, &di))
22329bd2886SAlan Wright return (NT_STATUS_CANT_ACCESS_DOMAIN_INFO);
2247f667e74Sjose borrego
22529bd2886SAlan Wright if (smb_sid_cmp(sid, di.di_binsid)) {
22629bd2886SAlan Wright /* This is the local domain SID */
22729bd2886SAlan Wright account->a_type = SidTypeDomain;
22829bd2886SAlan Wright account->a_name = strdup("");
22929bd2886SAlan Wright account->a_domain = strdup(di.di_nbname);
23029bd2886SAlan Wright account->a_sid = smb_sid_dup(sid);
23129bd2886SAlan Wright account->a_domsid = smb_sid_dup(sid);
23229bd2886SAlan Wright account->a_rid = (uint32_t)-1;
23329bd2886SAlan Wright
23429bd2886SAlan Wright if (!smb_account_validate(account)) {
23529bd2886SAlan Wright smb_account_free(account);
23629bd2886SAlan Wright return (NT_STATUS_NO_MEMORY);
23729bd2886SAlan Wright }
23829bd2886SAlan Wright
23929bd2886SAlan Wright return (NT_STATUS_SUCCESS);
24029bd2886SAlan Wright }
24129bd2886SAlan Wright
24229bd2886SAlan Wright if (!smb_sid_indomain(di.di_binsid, sid)) {
24329bd2886SAlan Wright /* This is not a local SID */
24429bd2886SAlan Wright return (NT_STATUS_NOT_FOUND);
24529bd2886SAlan Wright }
24629bd2886SAlan Wright
24729bd2886SAlan Wright if ((lwka = smb_lwka_lookup_sid(sid)) != NULL) {
24829bd2886SAlan Wright account->a_type = lwka->lwka_type;
24929bd2886SAlan Wright account->a_name = strdup(lwka->lwka_name);
25029bd2886SAlan Wright } else {
2517f667e74Sjose borrego id_type = SMB_IDMAP_UNKNOWN;
2527f667e74Sjose borrego if (smb_idmap_getid(sid, &id, &id_type) != IDMAP_SUCCESS)
2537f667e74Sjose borrego return (NT_STATUS_NONE_MAPPED);
2547f667e74Sjose borrego
2557f667e74Sjose borrego switch (id_type) {
2567f667e74Sjose borrego case SMB_IDMAP_USER:
2577f667e74Sjose borrego account->a_type = SidTypeUser;
2587f667e74Sjose borrego if (smb_pwd_getpwuid(id, &smbpw) == NULL)
2597f667e74Sjose borrego return (NT_STATUS_NO_SUCH_USER);
2607f667e74Sjose borrego
2617f667e74Sjose borrego account->a_name = strdup(smbpw.pw_name);
2627f667e74Sjose borrego break;
2637f667e74Sjose borrego
2647f667e74Sjose borrego case SMB_IDMAP_GROUP:
2657f667e74Sjose borrego account->a_type = SidTypeAlias;
2667f667e74Sjose borrego (void) smb_sid_getrid(sid, &rid);
2679fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States rc = smb_lgrp_getbyrid(rid, SMB_DOMAIN_LOCAL, &grp);
2687f667e74Sjose borrego if (rc != SMB_LGRP_SUCCESS)
2697f667e74Sjose borrego return (NT_STATUS_NO_SUCH_ALIAS);
2707f667e74Sjose borrego
2717f667e74Sjose borrego account->a_name = strdup(grp.sg_name);
2727f667e74Sjose borrego smb_lgrp_free(&grp);
2737f667e74Sjose borrego break;
2747f667e74Sjose borrego
2757f667e74Sjose borrego default:
2767f667e74Sjose borrego return (NT_STATUS_NONE_MAPPED);
2777f667e74Sjose borrego }
27829bd2886SAlan Wright }
2797f667e74Sjose borrego
2807f667e74Sjose borrego if (smb_getnetbiosname(hostname, MAXHOSTNAMELEN) == 0)
2817f667e74Sjose borrego account->a_domain = strdup(hostname);
2827f667e74Sjose borrego account->a_sid = smb_sid_dup(sid);
2837f667e74Sjose borrego account->a_domsid = smb_sid_split(sid, &account->a_rid);
2847f667e74Sjose borrego
2857f667e74Sjose borrego if (!smb_account_validate(account)) {
2867f667e74Sjose borrego smb_account_free(account);
2877f667e74Sjose borrego return (NT_STATUS_NO_MEMORY);
2887f667e74Sjose borrego }
2897f667e74Sjose borrego
2907f667e74Sjose borrego return (NT_STATUS_SUCCESS);
2917f667e74Sjose borrego }
2927f667e74Sjose borrego
2937f667e74Sjose borrego /*
2947f667e74Sjose borrego * Returns number of SMB users, i.e. users who have entry
2957f667e74Sjose borrego * in /var/smb/smbpasswd
2967f667e74Sjose borrego */
2977f667e74Sjose borrego int
smb_sam_usr_cnt(void)2987f667e74Sjose borrego smb_sam_usr_cnt(void)
2997f667e74Sjose borrego {
3007f667e74Sjose borrego return (smb_pwd_num());
3017f667e74Sjose borrego }
3027f667e74Sjose borrego
3037f667e74Sjose borrego /*
30436a00406SGordon Ross * Updates a list of groups in which the given user is a member
30536a00406SGordon Ross * by adding any local (SAM) groups.
30636a00406SGordon Ross *
30736a00406SGordon Ross * We are a member of local groups where the local group
30836a00406SGordon Ross * contains either the user's primary SID, or any of their
30936a00406SGordon Ross * other SIDs such as from domain groups, SID history, etc.
31036a00406SGordon Ross * We can have indirect membership via domain groups.
3117f667e74Sjose borrego */
3127f667e74Sjose borrego uint32_t
smb_sam_usr_groups(smb_sid_t * user_sid,smb_ids_t * gids)3137f667e74Sjose borrego smb_sam_usr_groups(smb_sid_t *user_sid, smb_ids_t *gids)
3147f667e74Sjose borrego {
31536a00406SGordon Ross smb_ids_t new_gids;
31636a00406SGordon Ross smb_id_t *ids, *new_ids;
3177f667e74Sjose borrego smb_giter_t gi;
3187f667e74Sjose borrego smb_group_t lgrp;
31936a00406SGordon Ross int i, gcnt, total_cnt;
32036a00406SGordon Ross uint32_t ret;
32136a00406SGordon Ross boolean_t member;
3227f667e74Sjose borrego
32336a00406SGordon Ross /*
32436a00406SGordon Ross * First pass: count groups to be added (gcnt)
32536a00406SGordon Ross */
3267f667e74Sjose borrego gcnt = 0;
3277f667e74Sjose borrego if (smb_lgrp_iteropen(&gi) != SMB_LGRP_SUCCESS)
3287f667e74Sjose borrego return (NT_STATUS_INTERNAL_ERROR);
3297f667e74Sjose borrego
3307f667e74Sjose borrego while (smb_lgrp_iterate(&gi, &lgrp) == SMB_LGRP_SUCCESS) {
33136a00406SGordon Ross member = B_FALSE;
3327f667e74Sjose borrego if (smb_lgrp_is_member(&lgrp, user_sid))
33336a00406SGordon Ross member = B_TRUE;
33436a00406SGordon Ross else for (i = 0, ids = gids->i_ids;
33536a00406SGordon Ross i < gids->i_cnt; i++, ids++) {
33636a00406SGordon Ross if (smb_lgrp_is_member(&lgrp, ids->i_sid)) {
33736a00406SGordon Ross member = B_TRUE;
33836a00406SGordon Ross break;
33936a00406SGordon Ross }
34036a00406SGordon Ross }
34136a00406SGordon Ross /* Careful: only count lgrp once */
34236a00406SGordon Ross if (member)
3437f667e74Sjose borrego gcnt++;
3447f667e74Sjose borrego smb_lgrp_free(&lgrp);
3457f667e74Sjose borrego }
3467f667e74Sjose borrego smb_lgrp_iterclose(&gi);
3477f667e74Sjose borrego
3487f667e74Sjose borrego if (gcnt == 0)
3497f667e74Sjose borrego return (NT_STATUS_SUCCESS);
3507f667e74Sjose borrego
35136a00406SGordon Ross /*
35236a00406SGordon Ross * Second pass: add to groups list.
35336a00406SGordon Ross * Do not modify gcnt after here.
35436a00406SGordon Ross */
3557f667e74Sjose borrego if (smb_lgrp_iteropen(&gi) != SMB_LGRP_SUCCESS)
3567f667e74Sjose borrego return (NT_STATUS_INTERNAL_ERROR);
3577f667e74Sjose borrego
35836a00406SGordon Ross /*
35936a00406SGordon Ross * Expand the list (copy to a new, larger one)
36036a00406SGordon Ross * Note: were're copying pointers from the old
36136a00406SGordon Ross * array to the new (larger) array, and then
36236a00406SGordon Ross * adding new pointers after what we copied.
36336a00406SGordon Ross */
36436a00406SGordon Ross ret = 0;
36536a00406SGordon Ross new_gids.i_cnt = gids->i_cnt;
36636a00406SGordon Ross total_cnt = gids->i_cnt + gcnt;
36736a00406SGordon Ross new_gids.i_ids = malloc(total_cnt * sizeof (smb_id_t));
36836a00406SGordon Ross if (new_gids.i_ids == NULL) {
36936a00406SGordon Ross ret = NT_STATUS_NO_MEMORY;
37036a00406SGordon Ross goto out;
37136a00406SGordon Ross }
37236a00406SGordon Ross (void) memcpy(new_gids.i_ids, gids->i_ids,
37336a00406SGordon Ross gids->i_cnt * sizeof (smb_id_t));
37436a00406SGordon Ross new_ids = new_gids.i_ids + gids->i_cnt;
37536a00406SGordon Ross (void) memset(new_ids, 0, gcnt * sizeof (smb_id_t));
37636a00406SGordon Ross
37736a00406SGordon Ross /*
37836a00406SGordon Ross * Add group SIDs starting at the end of the
37936a00406SGordon Ross * previous list. (new_ids)
38036a00406SGordon Ross */
3817f667e74Sjose borrego while (smb_lgrp_iterate(&gi, &lgrp) == SMB_LGRP_SUCCESS) {
38236a00406SGordon Ross member = B_FALSE;
38336a00406SGordon Ross if (smb_lgrp_is_member(&lgrp, user_sid))
38436a00406SGordon Ross member = B_TRUE;
38536a00406SGordon Ross else for (i = 0, ids = gids->i_ids;
38636a00406SGordon Ross i < gids->i_cnt; i++, ids++) {
38736a00406SGordon Ross if (smb_lgrp_is_member(&lgrp, ids->i_sid)) {
38836a00406SGordon Ross member = B_TRUE;
3897f667e74Sjose borrego break;
3907f667e74Sjose borrego }
3917f667e74Sjose borrego }
39236a00406SGordon Ross if (member && (new_gids.i_cnt < (gids->i_cnt + gcnt))) {
39336a00406SGordon Ross new_ids->i_sid = smb_sid_dup(lgrp.sg_id.gs_sid);
39436a00406SGordon Ross if (new_ids->i_sid == NULL) {
39536a00406SGordon Ross smb_lgrp_free(&lgrp);
39636a00406SGordon Ross ret = NT_STATUS_NO_MEMORY;
39736a00406SGordon Ross goto out;
39836a00406SGordon Ross }
39936a00406SGordon Ross new_ids->i_attrs = lgrp.sg_attr;
40036a00406SGordon Ross new_ids++;
40136a00406SGordon Ross new_gids.i_cnt++;
4027f667e74Sjose borrego }
4037f667e74Sjose borrego smb_lgrp_free(&lgrp);
4047f667e74Sjose borrego }
40536a00406SGordon Ross
40636a00406SGordon Ross out:
4077f667e74Sjose borrego smb_lgrp_iterclose(&gi);
4087f667e74Sjose borrego
40936a00406SGordon Ross if (ret != 0) {
41036a00406SGordon Ross if (new_gids.i_ids != NULL) {
41136a00406SGordon Ross /*
41236a00406SGordon Ross * Free only the new sids we added.
41336a00406SGordon Ross * The old ones were copied ptrs.
41436a00406SGordon Ross */
41536a00406SGordon Ross ids = new_gids.i_ids + gids->i_cnt;
41636a00406SGordon Ross for (i = 0; i < gcnt; i++, ids++) {
41736a00406SGordon Ross smb_sid_free(ids->i_sid);
41836a00406SGordon Ross }
41936a00406SGordon Ross free(new_gids.i_ids);
42036a00406SGordon Ross }
42136a00406SGordon Ross return (ret);
42236a00406SGordon Ross }
42336a00406SGordon Ross
42436a00406SGordon Ross /*
42536a00406SGordon Ross * Success! Update passed gids and
42636a00406SGordon Ross * free the old array.
42736a00406SGordon Ross */
42836a00406SGordon Ross free(gids->i_ids);
42936a00406SGordon Ross *gids = new_gids;
43036a00406SGordon Ross
4317f667e74Sjose borrego return (NT_STATUS_SUCCESS);
4327f667e74Sjose borrego }
4337f667e74Sjose borrego
4347f667e74Sjose borrego /*
4357f667e74Sjose borrego * Returns the number of built-in or local groups stored
4367f667e74Sjose borrego * in /var/smb/smbgroup.db
4377f667e74Sjose borrego */
4387f667e74Sjose borrego int
smb_sam_grp_cnt(smb_domain_type_t dtype)439a0aa776eSAlan Wright smb_sam_grp_cnt(smb_domain_type_t dtype)
4407f667e74Sjose borrego {
4417f667e74Sjose borrego int grpcnt;
4427f667e74Sjose borrego int rc;
4437f667e74Sjose borrego
4447f667e74Sjose borrego switch (dtype) {
445a0aa776eSAlan Wright case SMB_DOMAIN_BUILTIN:
4469fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States rc = smb_lgrp_numbydomain(SMB_DOMAIN_BUILTIN, &grpcnt);
4477f667e74Sjose borrego break;
4487f667e74Sjose borrego
449a0aa776eSAlan Wright case SMB_DOMAIN_LOCAL:
4509fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States rc = smb_lgrp_numbydomain(SMB_DOMAIN_LOCAL, &grpcnt);
4517f667e74Sjose borrego break;
4527f667e74Sjose borrego
4537f667e74Sjose borrego default:
4547f667e74Sjose borrego rc = SMB_LGRP_INVALID_ARG;
4557f667e74Sjose borrego }
4567f667e74Sjose borrego
4577f667e74Sjose borrego return ((rc == SMB_LGRP_SUCCESS) ? grpcnt : 0);
4587f667e74Sjose borrego }
4597f667e74Sjose borrego
4607f667e74Sjose borrego /*
4617f667e74Sjose borrego * Determines whether the given SID is a member of the group
4627f667e74Sjose borrego * specified by gname.
4637f667e74Sjose borrego */
4647f667e74Sjose borrego boolean_t
smb_sam_grp_ismember(const char * gname,smb_sid_t * sid)4657f667e74Sjose borrego smb_sam_grp_ismember(const char *gname, smb_sid_t *sid)
4667f667e74Sjose borrego {
4677f667e74Sjose borrego smb_group_t grp;
4687f667e74Sjose borrego boolean_t ismember = B_FALSE;
4697f667e74Sjose borrego
4707f667e74Sjose borrego if (smb_lgrp_getbyname((char *)gname, &grp) == SMB_LGRP_SUCCESS) {
4717f667e74Sjose borrego ismember = smb_lgrp_is_member(&grp, sid);
4727f667e74Sjose borrego smb_lgrp_free(&grp);
4737f667e74Sjose borrego }
4747f667e74Sjose borrego
4757f667e74Sjose borrego return (ismember);
4767f667e74Sjose borrego }
4777f667e74Sjose borrego
4787f667e74Sjose borrego /*
4797f667e74Sjose borrego * Frees memories allocated for the passed account fields.
4807f667e74Sjose borrego */
4817f667e74Sjose borrego void
smb_account_free(smb_account_t * account)4827f667e74Sjose borrego smb_account_free(smb_account_t *account)
4837f667e74Sjose borrego {
4847f667e74Sjose borrego free(account->a_name);
4857f667e74Sjose borrego free(account->a_domain);
4867f667e74Sjose borrego smb_sid_free(account->a_sid);
4877f667e74Sjose borrego smb_sid_free(account->a_domsid);
4887f667e74Sjose borrego }
4897f667e74Sjose borrego
4907f667e74Sjose borrego /*
4917f667e74Sjose borrego * Validates the given account.
4927f667e74Sjose borrego */
4937f667e74Sjose borrego boolean_t
smb_account_validate(smb_account_t * account)4947f667e74Sjose borrego smb_account_validate(smb_account_t *account)
4957f667e74Sjose borrego {
4967f667e74Sjose borrego return ((account->a_name != NULL) && (account->a_sid != NULL) &&
4977f667e74Sjose borrego (account->a_domain != NULL) && (account->a_domsid != NULL));
4987f667e74Sjose borrego }
4997f667e74Sjose borrego
5007f667e74Sjose borrego /*
5017f667e74Sjose borrego * Lookup local SMB user account database (/var/smb/smbpasswd)
5027f667e74Sjose borrego * if there's a match query its SID from idmap service and make
5037f667e74Sjose borrego * sure the SID is a local SID.
5047f667e74Sjose borrego *
5057f667e74Sjose borrego * The memory for the returned SID must be freed by the caller.
5067f667e74Sjose borrego */
5077f667e74Sjose borrego static uint32_t
smb_sam_lookup_user(char * name,smb_sid_t ** sid)5087f667e74Sjose borrego smb_sam_lookup_user(char *name, smb_sid_t **sid)
5097f667e74Sjose borrego {
5107f667e74Sjose borrego smb_passwd_t smbpw;
5117f667e74Sjose borrego
5127f667e74Sjose borrego if (smb_pwd_getpwnam(name, &smbpw) == NULL)
5137f667e74Sjose borrego return (NT_STATUS_NO_SUCH_USER);
5147f667e74Sjose borrego
5157f667e74Sjose borrego if (smb_idmap_getsid(smbpw.pw_uid, SMB_IDMAP_USER, sid)
5167f667e74Sjose borrego != IDMAP_SUCCESS)
5177f667e74Sjose borrego return (NT_STATUS_NONE_MAPPED);
5187f667e74Sjose borrego
5197f667e74Sjose borrego if (!smb_sid_islocal(*sid)) {
5207f667e74Sjose borrego smb_sid_free(*sid);
5217f667e74Sjose borrego return (NT_STATUS_NONE_MAPPED);
5227f667e74Sjose borrego }
5237f667e74Sjose borrego
5247f667e74Sjose borrego return (NT_STATUS_SUCCESS);
5257f667e74Sjose borrego }
5267f667e74Sjose borrego
5277f667e74Sjose borrego /*
5287f667e74Sjose borrego * Lookup local SMB group account database (/var/smb/smbgroup.db)
5297f667e74Sjose borrego * The memory for the returned SID must be freed by the caller.
5307f667e74Sjose borrego */
5317f667e74Sjose borrego static uint32_t
smb_sam_lookup_group(char * name,smb_sid_t ** sid)5327f667e74Sjose borrego smb_sam_lookup_group(char *name, smb_sid_t **sid)
5337f667e74Sjose borrego {
5347f667e74Sjose borrego smb_group_t grp;
5357f667e74Sjose borrego
5367f667e74Sjose borrego if (smb_lgrp_getbyname(name, &grp) != SMB_LGRP_SUCCESS)
5377f667e74Sjose borrego return (NT_STATUS_NO_SUCH_ALIAS);
5387f667e74Sjose borrego
5397f667e74Sjose borrego *sid = smb_sid_dup(grp.sg_id.gs_sid);
5407f667e74Sjose borrego smb_lgrp_free(&grp);
5417f667e74Sjose borrego
5427f667e74Sjose borrego return ((*sid == NULL) ? NT_STATUS_NO_MEMORY : NT_STATUS_SUCCESS);
5437f667e74Sjose borrego }
54429bd2886SAlan Wright
54529bd2886SAlan Wright static smb_lwka_t *
smb_lwka_lookup_name(char * name)54629bd2886SAlan Wright smb_lwka_lookup_name(char *name)
54729bd2886SAlan Wright {
54829bd2886SAlan Wright int i;
54929bd2886SAlan Wright
55029bd2886SAlan Wright for (i = 0; i < SMB_LWKA_NUM; i++) {
551bbf6f00cSJordan Brown if (smb_strcasecmp(name, lwka_tbl[i].lwka_name, 0) == 0)
55229bd2886SAlan Wright return (&lwka_tbl[i]);
55329bd2886SAlan Wright }
55429bd2886SAlan Wright
55529bd2886SAlan Wright return (NULL);
55629bd2886SAlan Wright }
55729bd2886SAlan Wright
55829bd2886SAlan Wright static smb_lwka_t *
smb_lwka_lookup_sid(smb_sid_t * sid)55929bd2886SAlan Wright smb_lwka_lookup_sid(smb_sid_t *sid)
56029bd2886SAlan Wright {
56129bd2886SAlan Wright uint32_t rid;
56229bd2886SAlan Wright int i;
56329bd2886SAlan Wright
56429bd2886SAlan Wright (void) smb_sid_getrid(sid, &rid);
56529bd2886SAlan Wright if (rid > 999)
56629bd2886SAlan Wright return (NULL);
56729bd2886SAlan Wright
56829bd2886SAlan Wright for (i = 0; i < SMB_LWKA_NUM; i++) {
56929bd2886SAlan Wright if (rid == lwka_tbl[i].lwka_rid)
57029bd2886SAlan Wright return (&lwka_tbl[i]);
57129bd2886SAlan Wright }
57229bd2886SAlan Wright
57329bd2886SAlan Wright return (NULL);
57429bd2886SAlan Wright }
575*7206bf49SGordon Ross
576*7206bf49SGordon Ross /*
577*7206bf49SGordon Ross * smb_sid_islocal
578*7206bf49SGordon Ross *
579*7206bf49SGordon Ross * Check a SID to see if it belongs to the local domain.
580*7206bf49SGordon Ross */
581*7206bf49SGordon Ross boolean_t
smb_sid_islocal(smb_sid_t * sid)582*7206bf49SGordon Ross smb_sid_islocal(smb_sid_t *sid)
583*7206bf49SGordon Ross {
584*7206bf49SGordon Ross smb_domain_t di;
585*7206bf49SGordon Ross boolean_t islocal = B_FALSE;
586*7206bf49SGordon Ross
587*7206bf49SGordon Ross if (smb_domain_lookup_type(SMB_DOMAIN_LOCAL, &di))
588*7206bf49SGordon Ross islocal = smb_sid_indomain(di.di_binsid, sid);
589*7206bf49SGordon Ross
590*7206bf49SGordon Ross return (islocal);
591*7206bf49SGordon Ross }
592*7206bf49SGordon Ross
593*7206bf49SGordon Ross void
smb_ids_free(smb_ids_t * ids)594*7206bf49SGordon Ross smb_ids_free(smb_ids_t *ids)
595*7206bf49SGordon Ross {
596*7206bf49SGordon Ross smb_id_t *id;
597*7206bf49SGordon Ross int i;
598*7206bf49SGordon Ross
599*7206bf49SGordon Ross if ((ids != NULL) && (ids->i_ids != NULL)) {
600*7206bf49SGordon Ross id = ids->i_ids;
601*7206bf49SGordon Ross for (i = 0; i < ids->i_cnt; i++, id++)
602*7206bf49SGordon Ross smb_sid_free(id->i_sid);
603*7206bf49SGordon Ross
604*7206bf49SGordon Ross free(ids->i_ids);
605*7206bf49SGordon Ross }
606*7206bf49SGordon Ross }
607