xref: /titanic_51/usr/src/lib/smbsrv/libsmb/common/smb_lgrp.c (revision a7fe1d5bb55904d4c79638b8778bc9dd8ed7fd7b)
1dc20a302Sas200622 /*
2dc20a302Sas200622  * CDDL HEADER START
3dc20a302Sas200622  *
4dc20a302Sas200622  * The contents of this file are subject to the terms of the
5dc20a302Sas200622  * Common Development and Distribution License (the "License").
6dc20a302Sas200622  * You may not use this file except in compliance with the License.
7dc20a302Sas200622  *
8dc20a302Sas200622  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9dc20a302Sas200622  * or http://www.opensolaris.org/os/licensing.
10dc20a302Sas200622  * See the License for the specific language governing permissions
11dc20a302Sas200622  * and limitations under the License.
12dc20a302Sas200622  *
13dc20a302Sas200622  * When distributing Covered Code, include this CDDL HEADER in each
14dc20a302Sas200622  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15dc20a302Sas200622  * If applicable, add the following below this CDDL HEADER, with the
16dc20a302Sas200622  * fields enclosed by brackets "[]" replaced with your own identifying
17dc20a302Sas200622  * information: Portions Copyright [yyyy] [name of copyright owner]
18dc20a302Sas200622  *
19dc20a302Sas200622  * CDDL HEADER END
20dc20a302Sas200622  */
21148c5f43SAlan Wright 
22dc20a302Sas200622 /*
2336a00406SGordon Ross  * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
24c5866007SKeyur Desai  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
25*a7fe1d5bSAndy Stormont  * Copyright (c) 2013 RackTop Systems.
26dc20a302Sas200622  */
27dc20a302Sas200622 
28dc20a302Sas200622 #include <stdlib.h>
29dc20a302Sas200622 #include <strings.h>
30dc20a302Sas200622 #include <unistd.h>
31dc20a302Sas200622 #include <syslog.h>
32dc20a302Sas200622 #include <thread.h>
33dc20a302Sas200622 #include <synch.h>
34dc20a302Sas200622 #include <grp.h>
35dc20a302Sas200622 #include <assert.h>
36dc20a302Sas200622 #include <libintl.h>
37dc20a302Sas200622 #include <smbsrv/libsmb.h>
387b59d02dSjb150015 #include <smb_sqlite.h>
39148c5f43SAlan Wright #include <sys/types.h>
40148c5f43SAlan Wright #include <sys/stat.h>
41148c5f43SAlan Wright #include <sys/param.h>
42*a7fe1d5bSAndy Stormont #include <libcmdutils.h>
43dc20a302Sas200622 
44faa1795aSjb150015 /*
45faa1795aSjb150015  * Local domain SID (aka machine SID) is not stored in the domain table
46faa1795aSjb150015  * therefore the index is 0
47faa1795aSjb150015  */
48dc20a302Sas200622 #define	SMB_LGRP_LOCAL_IDX	0
49dc20a302Sas200622 #define	SMB_LGRP_BUILTIN_IDX	1
50dc20a302Sas200622 
51dc20a302Sas200622 #define	SMB_LGRP_DB_NAME	"/var/smb/smbgroup.db"
52dc20a302Sas200622 #define	SMB_LGRP_DB_TIMEOUT	3000		/* in millisecond */
53dc20a302Sas200622 #define	SMB_LGRP_DB_VERMAJOR	1
54dc20a302Sas200622 #define	SMB_LGRP_DB_VERMINOR	0
55dc20a302Sas200622 #define	SMB_LGRP_DB_MAGIC	0x4C475250	/* LGRP */
56dc20a302Sas200622 
57dc20a302Sas200622 #define	SMB_LGRP_DB_ORD		1		/* open read-only */
58dc20a302Sas200622 #define	SMB_LGRP_DB_ORW		2		/* open read/write */
59dc20a302Sas200622 
60dc20a302Sas200622 #define	SMB_LGRP_DB_ADDMEMBER	1
61dc20a302Sas200622 #define	SMB_LGRP_DB_DELMEMBER	2
62dc20a302Sas200622 
63dc20a302Sas200622 /*
64dc20a302Sas200622  * members column of the groups table is an array of
65dc20a302Sas200622  * member structure smb_lgmid_t defined below.
66dc20a302Sas200622  *
67dc20a302Sas200622  * privs column of the groups table is an array of bytes
68dc20a302Sas200622  * where each byte is the id of an enable privilege
69dc20a302Sas200622  */
70dc20a302Sas200622 #define	SMB_LGRP_DB_SQL \
71dc20a302Sas200622 	"CREATE TABLE db_info ("				\
72dc20a302Sas200622 	"	ver_major INTEGER,"				\
73dc20a302Sas200622 	"	ver_minor INTEGER,"				\
74dc20a302Sas200622 	"	magic     INTEGER"				\
75dc20a302Sas200622 	");"							\
76dc20a302Sas200622 	""							\
77dc20a302Sas200622 	"CREATE TABLE domains ("				\
78dc20a302Sas200622 	"	dom_idx INTEGER PRIMARY KEY,"			\
79dc20a302Sas200622 	"	dom_sid TEXT UNIQUE,"				\
80dc20a302Sas200622 	"       dom_cnt INTEGER"				\
81dc20a302Sas200622 	");"							\
82dc20a302Sas200622 	""							\
83dc20a302Sas200622 	"CREATE UNIQUE INDEX domsid_idx ON domains (dom_sid);"	\
84dc20a302Sas200622 	""							\
85dc20a302Sas200622 	"CREATE TABLE groups ("					\
86dc20a302Sas200622 	"	name      TEXT PRIMARY KEY,"			\
87dc20a302Sas200622 	"	sid_idx   INTEGER,"				\
88dc20a302Sas200622 	"	sid_rid   INTEGER,"				\
89dc20a302Sas200622 	"	sid_type  INTEGER,"				\
90dc20a302Sas200622 	"	sid_attrs INTEGER,"				\
91dc20a302Sas200622 	"	comment   TEXT,"				\
92dc20a302Sas200622 	"	n_privs   INTEGER,"				\
93dc20a302Sas200622 	"	privs     BLOB,"				\
94dc20a302Sas200622 	"	n_members INTEGER,"				\
95dc20a302Sas200622 	"	members   BLOB"					\
96dc20a302Sas200622 	");"							\
97dc20a302Sas200622 	""							\
98dc20a302Sas200622 	"CREATE INDEX grprid_idx ON groups (sid_rid);"
99dc20a302Sas200622 
100dc20a302Sas200622 /*
101dc20a302Sas200622  * Number of groups table columns
102dc20a302Sas200622  */
103dc20a302Sas200622 #define	SMB_LGRP_GTBL_NCOL	10
104dc20a302Sas200622 
105dc20a302Sas200622 #define	SMB_LGRP_GTBL_NAME	0
106dc20a302Sas200622 #define	SMB_LGRP_GTBL_SIDIDX	1
107dc20a302Sas200622 #define	SMB_LGRP_GTBL_SIDRID	2
108dc20a302Sas200622 #define	SMB_LGRP_GTBL_SIDTYP	3
109dc20a302Sas200622 #define	SMB_LGRP_GTBL_SIDATR	4
110dc20a302Sas200622 #define	SMB_LGRP_GTBL_CMNT	5
111dc20a302Sas200622 #define	SMB_LGRP_GTBL_NPRIVS	6
112dc20a302Sas200622 #define	SMB_LGRP_GTBL_PRIVS	7
113dc20a302Sas200622 #define	SMB_LGRP_GTBL_NMEMBS	8
114dc20a302Sas200622 #define	SMB_LGRP_GTBL_MEMBS	9
115dc20a302Sas200622 
116dc20a302Sas200622 #define	SMB_LGRP_INFO_NONE	0x00
117dc20a302Sas200622 #define	SMB_LGRP_INFO_NAME	0x01
118dc20a302Sas200622 #define	SMB_LGRP_INFO_CMNT	0x02
119dc20a302Sas200622 #define	SMB_LGRP_INFO_SID	0x04
120dc20a302Sas200622 #define	SMB_LGRP_INFO_PRIV	0x08
121dc20a302Sas200622 #define	SMB_LGRP_INFO_MEMB	0x10
122dc20a302Sas200622 #define	SMB_LGRP_INFO_ALL	0x1F
123dc20a302Sas200622 
124148c5f43SAlan Wright #define	SMB_LGRP_PGRP_GRPTMP	"/etc/gtmp"
125148c5f43SAlan Wright #define	SMB_LGRP_PGRP_GRPBUFSIZ	5120
126148c5f43SAlan Wright #define	SMB_LGRP_PGRP_GROUP	"/etc/group"
127148c5f43SAlan Wright #define	SMB_LGRP_PGRP_MAXGLEN	9	/* max length of group name */
128*a7fe1d5bSAndy Stormont #define	SMB_LGRP_PGRP_DEFRID	1000	/* lowest cifs created gid */
129148c5f43SAlan Wright 
130148c5f43SAlan Wright #define	SMB_LGRP_PGRP_NOTUNIQUE	0
131148c5f43SAlan Wright #define	SMB_LGRP_PGRP_RESERVED	1
132148c5f43SAlan Wright #define	SMB_LGRP_PGRP_UNIQUE	2
133148c5f43SAlan Wright #define	SMB_LGRP_PGRP_TOOBIG	3
134148c5f43SAlan Wright #define	SMB_LGRP_PGRP_INVALID	4
135148c5f43SAlan Wright 
136dc20a302Sas200622 #define	NULL_MSGCHK(msg)	((msg) ? (msg) : "NULL")
137dc20a302Sas200622 
138dc20a302Sas200622 /* Member ID */
139dc20a302Sas200622 typedef struct smb_lgmid {
140dc20a302Sas200622 	uint32_t m_idx;
141dc20a302Sas200622 	uint32_t m_rid;
142dc20a302Sas200622 	uint16_t m_type;
143dc20a302Sas200622 } smb_lgmid_t;
144dc20a302Sas200622 
145dc20a302Sas200622 #define	SMB_LGRP_MID_HEXSZ	32
146dc20a302Sas200622 
147dc20a302Sas200622 /* Member list */
148dc20a302Sas200622 typedef struct smb_lgmlist {
149dc20a302Sas200622 	uint32_t	m_cnt;
150dc20a302Sas200622 	char		*m_ids;
151dc20a302Sas200622 } smb_lgmlist_t;
152dc20a302Sas200622 
153dc20a302Sas200622 /* Privilege ID */
154dc20a302Sas200622 typedef uint8_t smb_lgpid_t;
155dc20a302Sas200622 
156dc20a302Sas200622 /* Privilege list */
157dc20a302Sas200622 typedef struct smb_lgplist {
158dc20a302Sas200622 	uint32_t	p_cnt;
159dc20a302Sas200622 	smb_lgpid_t	*p_ids;
160dc20a302Sas200622 } smb_lgplist_t;
161dc20a302Sas200622 
1629fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static struct {
1639fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	int	errnum;
1649fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	char	*errmsg;
1659fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } errtab[] = {
1669fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	{ SMB_LGRP_SUCCESS,		"success" },
1679fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	{ SMB_LGRP_INVALID_ARG,		"invalid argument" },
1689fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	{ SMB_LGRP_INVALID_MEMBER,	"invalid member type" },
1699fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	{ SMB_LGRP_INVALID_NAME,	"invalid name" },
1709fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	{ SMB_LGRP_NOT_FOUND,		"group not found" },
1719fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	{ SMB_LGRP_EXISTS,		"group exists" },
1729fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	{ SMB_LGRP_NO_SID,		"cannot obtain a SID" },
1739fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	{ SMB_LGRP_NO_LOCAL_SID,	"cannot get the machine SID" },
1749fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	{ SMB_LGRP_SID_NOTLOCAL,	"local account has non-local SID" },
1759fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	{ SMB_LGRP_WKSID,
1769fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		"operation not permitted on well-known account" },
1779fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	{ SMB_LGRP_NO_MEMORY,		"not enough memory" },
1789fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	{ SMB_LGRP_DB_ERROR,		"database operation error" },
1799fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	{ SMB_LGRP_DBINIT_ERROR,	"database initialization error" },
1809fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	{ SMB_LGRP_INTERNAL_ERROR,	"internal error" },
1819fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	{ SMB_LGRP_MEMBER_IN_GROUP,	"member already in group" },
1829fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	{ SMB_LGRP_MEMBER_NOT_IN_GROUP,	"not a member" },
1839fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	{ SMB_LGRP_NO_SUCH_PRIV,	"no such privilege" },
1849fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	{ SMB_LGRP_NO_SUCH_DOMAIN,	"no such domain SID" },
1859fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	{ SMB_LGRP_PRIV_HELD,		"privilege already held" },
1869fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	{ SMB_LGRP_PRIV_NOT_HELD,	"privilege not held" },
1879fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	{ SMB_LGRP_BAD_DATA,		"bad data" },
1889fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	{ SMB_LGRP_NO_MORE,		"no more groups" },
1899fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	{ SMB_LGRP_DBOPEN_FAILED,	"database open failed" },
1909fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	{ SMB_LGRP_DBEXEC_FAILED,	"database operation failed" },
1919fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	{ SMB_LGRP_DBINIT_FAILED,	"database initialization failed" },
1929fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	{ SMB_LGRP_DOMLKP_FAILED,	"domain SID lookup failed" },
1939fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	{ SMB_LGRP_DOMINS_FAILED,	"domain SID insert failed" },
1949fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	{ SMB_LGRP_INSERT_FAILED,	"group insert failed" },
1959fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	{ SMB_LGRP_DELETE_FAILED,	"group delete failed" },
1969fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	{ SMB_LGRP_UPDATE_FAILED,	"group update failed" },
1979fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	{ SMB_LGRP_LOOKUP_FAILED,	"group lookup failed" },
198148c5f43SAlan Wright 	{ SMB_LGRP_OFFLINE,		"local group service is offline" },
199148c5f43SAlan Wright 	{ SMB_LGRP_POSIXCREATE_FAILED,	"posix group create failed" }
2009fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States };
201dc20a302Sas200622 
2029fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
2039fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Serialization for the local group API.
2049fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
2059fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States typedef struct {
2069fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	mutex_t		lg_mutex;
2079fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	cond_t		lg_cv;
2089fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	boolean_t	lg_online;
2099fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	uint32_t	lg_refcnt;
2109fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_sid_t	*lg_machine_sid;
2119fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } smb_localgrp_t;
2129fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
2139fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static smb_localgrp_t smb_localgrp;
2149fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
2159fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static boolean_t smb_lgrp_enter(void);
2169fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static void smb_lgrp_exit(void);
217dc20a302Sas200622 static int smb_lgrp_db_init(void);
218dc20a302Sas200622 static sqlite *smb_lgrp_db_open(int);
219dc20a302Sas200622 static void smb_lgrp_db_close(sqlite *);
220dc20a302Sas200622 static int smb_lgrp_db_setinfo(sqlite *);
221dc20a302Sas200622 
222dc20a302Sas200622 static boolean_t smb_lgrp_gtbl_exists(sqlite *, char *);
223dc20a302Sas200622 static int smb_lgrp_gtbl_lookup(sqlite *, int, smb_group_t *, int, ...);
224dc20a302Sas200622 static int smb_lgrp_gtbl_insert(sqlite *, smb_group_t *);
225dc20a302Sas200622 static int smb_lgrp_gtbl_update(sqlite *, char *, smb_group_t *, int);
226dc20a302Sas200622 static int smb_lgrp_gtbl_delete(sqlite *, char *);
227dc20a302Sas200622 static int smb_lgrp_gtbl_update_mlist(sqlite *, char *, smb_gsid_t *, int);
228dc20a302Sas200622 static int smb_lgrp_gtbl_update_plist(sqlite *, char *, uint8_t, boolean_t);
229dc20a302Sas200622 static int smb_lgrp_gtbl_count(sqlite *, int, int *);
230dc20a302Sas200622 
231dc20a302Sas200622 static int smb_lgrp_dtbl_insert(sqlite *, char *, uint32_t *);
2326537f381Sas200622 static int smb_lgrp_dtbl_getidx(sqlite *, smb_sid_t *, uint16_t,
233dc20a302Sas200622     uint32_t *, uint32_t *);
2346537f381Sas200622 static int smb_lgrp_dtbl_getsid(sqlite *, uint32_t, smb_sid_t **);
235dc20a302Sas200622 
236dc20a302Sas200622 static int smb_lgrp_mlist_add(smb_lgmlist_t *, smb_lgmid_t *, smb_lgmlist_t *);
237dc20a302Sas200622 static int smb_lgrp_mlist_del(smb_lgmlist_t *, smb_lgmid_t *, smb_lgmlist_t *);
238dc20a302Sas200622 
239dc20a302Sas200622 static int smb_lgrp_plist_add(smb_lgplist_t *, smb_lgpid_t, smb_lgplist_t *);
240dc20a302Sas200622 static int smb_lgrp_plist_del(smb_lgplist_t *, smb_lgpid_t, smb_lgplist_t *);
241dc20a302Sas200622 
242dc20a302Sas200622 static void smb_lgrp_encode_privset(smb_group_t *, smb_lgplist_t *);
243dc20a302Sas200622 
244dc20a302Sas200622 static int smb_lgrp_decode(smb_group_t *, char **, int, sqlite *);
245dc20a302Sas200622 static int smb_lgrp_decode_privset(smb_group_t *, char *, char *);
246dc20a302Sas200622 static int smb_lgrp_decode_members(smb_group_t *, char *, char *, sqlite *);
247dc20a302Sas200622 
248dc20a302Sas200622 static void smb_lgrp_set_default_privs(smb_group_t *);
249fe1c642dSBill Krier static boolean_t smb_lgrp_normalize_name(char *);
250dc20a302Sas200622 static boolean_t smb_lgrp_chkmember(uint16_t);
2516537f381Sas200622 static int smb_lgrp_getsid(int, uint32_t *, uint16_t, sqlite *, smb_sid_t **);
252c8ec8eeaSjose borrego static int smb_lgrp_getgid(uint32_t rid, gid_t *gid);
25329bd2886SAlan Wright static boolean_t smb_lgrp_exists(char *);
254148c5f43SAlan Wright static int smb_lgrp_pgrp_add(char *);
255dc20a302Sas200622 
256dc20a302Sas200622 /*
257dc20a302Sas200622  * smb_lgrp_add
258dc20a302Sas200622  *
259dc20a302Sas200622  * Create a local group with the given name and comment.
260dc20a302Sas200622  * This new group doesn't have any members and no enabled
261dc20a302Sas200622  * privileges.
262dc20a302Sas200622  *
263dc20a302Sas200622  * No well-known accounts can be added other than Administators,
264dc20a302Sas200622  * Backup Operators and Power Users. These built-in groups
265dc20a302Sas200622  * won't have any members when created but a set of default
266dc20a302Sas200622  * privileges will be enabled for them.
267dc20a302Sas200622  */
268dc20a302Sas200622 int
269dc20a302Sas200622 smb_lgrp_add(char *gname, char *cmnt)
270dc20a302Sas200622 {
2716537f381Sas200622 	smb_wka_t *wka;
272dc20a302Sas200622 	struct group *pxgrp;
273dc20a302Sas200622 	smb_group_t grp;
2746537f381Sas200622 	smb_sid_t *sid = NULL;
275dc20a302Sas200622 	sqlite *db;
276dc20a302Sas200622 	int rc;
277dc20a302Sas200622 
278fe1c642dSBill Krier 	if (!smb_lgrp_normalize_name(gname))
279dc20a302Sas200622 		return (SMB_LGRP_INVALID_NAME);
280dc20a302Sas200622 
281dc20a302Sas200622 	if (cmnt && (strlen(cmnt) > SMB_LGRP_COMMENT_MAX))
282dc20a302Sas200622 		return (SMB_LGRP_INVALID_ARG);
283dc20a302Sas200622 
284dc20a302Sas200622 	bzero(&grp, sizeof (grp));
285bbf6f00cSJordan Brown 	grp.sg_name = smb_strlwr(gname);
286dc20a302Sas200622 	grp.sg_cmnt = cmnt;
287dc20a302Sas200622 
2889fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (!smb_lgrp_enter())
2899fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (SMB_LGRP_OFFLINE);
2909fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
2917f667e74Sjose borrego 	wka = smb_wka_lookup_name(gname);
2926537f381Sas200622 	if (wka == NULL) {
2939fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		if ((pxgrp = getgrnam(gname)) == NULL) {
294148c5f43SAlan Wright 			if (smb_lgrp_pgrp_add(gname) != 0) {
295148c5f43SAlan Wright 				smb_lgrp_exit();
296148c5f43SAlan Wright 				return (SMB_LGRP_POSIXCREATE_FAILED);
297148c5f43SAlan Wright 			}
298148c5f43SAlan Wright 
299148c5f43SAlan Wright 			if ((pxgrp = getgrnam(gname)) == NULL) {
3009fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 				smb_lgrp_exit();
301dc20a302Sas200622 				return (SMB_LGRP_NOT_FOUND);
3029fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			}
303148c5f43SAlan Wright 		}
304dc20a302Sas200622 
305dc20a302Sas200622 		/*
306dc20a302Sas200622 		 * Make sure a local SID can be obtained
307dc20a302Sas200622 		 */
308dc20a302Sas200622 		if (smb_idmap_getsid(pxgrp->gr_gid, SMB_IDMAP_GROUP, &sid)
3099fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		    != IDMAP_SUCCESS) {
3109fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			smb_lgrp_exit();
311dc20a302Sas200622 			return (SMB_LGRP_NO_SID);
3129fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		}
313dc20a302Sas200622 
3149fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		if (!smb_sid_indomain(smb_localgrp.lg_machine_sid, sid)) {
315dc20a302Sas200622 			free(sid);
3169fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			smb_lgrp_exit();
317dc20a302Sas200622 			return (SMB_LGRP_SID_NOTLOCAL);
318dc20a302Sas200622 		}
319dc20a302Sas200622 
3209fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		free(sid);
321dc20a302Sas200622 		grp.sg_id.gs_type = SidTypeAlias;
3229fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		grp.sg_domain = SMB_DOMAIN_LOCAL;
323dc20a302Sas200622 		grp.sg_rid = pxgrp->gr_gid;
324dc20a302Sas200622 	} else {
3256537f381Sas200622 		if ((wka->wka_flags & SMB_WKAFLG_LGRP_ENABLE) == 0) {
326dc20a302Sas200622 			/* cannot add well-known accounts */
3279fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			smb_lgrp_exit();
328dc20a302Sas200622 			return (SMB_LGRP_WKSID);
329dc20a302Sas200622 		}
330dc20a302Sas200622 
3316537f381Sas200622 		grp.sg_id.gs_type = wka->wka_type;
3329fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		if ((sid = smb_sid_fromstr(wka->wka_sid)) == NULL) {
3339fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			smb_lgrp_exit();
334dc20a302Sas200622 			return (SMB_LGRP_NO_MEMORY);
3359fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		}
3369fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
3376537f381Sas200622 		(void) smb_sid_getrid(sid, &grp.sg_rid);
338dc20a302Sas200622 		free(sid);
3399fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		grp.sg_domain = SMB_DOMAIN_BUILTIN;
340dc20a302Sas200622 		grp.sg_privs = smb_privset_new();
341dc20a302Sas200622 		smb_lgrp_set_default_privs(&grp);
342dc20a302Sas200622 	}
343dc20a302Sas200622 
3449fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (smb_lgrp_exists(grp.sg_name)) {
3459fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		smb_lgrp_exit();
34696a62adaSjoyce mcintosh 		return (SMB_LGRP_EXISTS);
3479fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
348dc20a302Sas200622 
349dc20a302Sas200622 	grp.sg_attr = SE_GROUP_MANDATORY | SE_GROUP_ENABLED_BY_DEFAULT |
350dc20a302Sas200622 	    SE_GROUP_ENABLED;
351dc20a302Sas200622 
352dc20a302Sas200622 	db = smb_lgrp_db_open(SMB_LGRP_DB_ORW);
353dc20a302Sas200622 	rc = smb_lgrp_gtbl_insert(db, &grp);
354dc20a302Sas200622 	smb_lgrp_db_close(db);
355dc20a302Sas200622 
356dc20a302Sas200622 	smb_privset_free(grp.sg_privs);
3579fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_lgrp_exit();
358dc20a302Sas200622 	return (rc);
359dc20a302Sas200622 }
360dc20a302Sas200622 
361dc20a302Sas200622 /*
362dc20a302Sas200622  * smb_lgrp_rename
363dc20a302Sas200622  *
364dc20a302Sas200622  * Renames the given group
365dc20a302Sas200622  */
366dc20a302Sas200622 int
367dc20a302Sas200622 smb_lgrp_rename(char *gname, char *new_gname)
368dc20a302Sas200622 {
369dc20a302Sas200622 	smb_group_t grp;
370dc20a302Sas200622 	sqlite *db;
371dc20a302Sas200622 	int rc;
372dc20a302Sas200622 
373fe1c642dSBill Krier 	if (!smb_lgrp_normalize_name(gname))
374dc20a302Sas200622 		return (SMB_LGRP_INVALID_NAME);
375dc20a302Sas200622 
376fe1c642dSBill Krier 	if (!smb_lgrp_normalize_name(gname))
377dc20a302Sas200622 		return (SMB_LGRP_INVALID_NAME);
378dc20a302Sas200622 
379bbf6f00cSJordan Brown 	if (smb_strcasecmp(gname, new_gname, 0) == 0)
380dc20a302Sas200622 		return (SMB_LGRP_SUCCESS);
381dc20a302Sas200622 
382dc20a302Sas200622 	/* Cannot rename well-known groups */
3837f667e74Sjose borrego 	if (smb_wka_lookup_name(gname) != NULL)
384dc20a302Sas200622 		return (SMB_LGRP_WKSID);
385dc20a302Sas200622 
386dc20a302Sas200622 	/* Cannot rename to a well-known groups */
3877f667e74Sjose borrego 	if (smb_wka_lookup_name(new_gname) != NULL)
388dc20a302Sas200622 		return (SMB_LGRP_WKSID);
389dc20a302Sas200622 
390dc20a302Sas200622 	grp.sg_name = new_gname;
391dc20a302Sas200622 
3929fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (!smb_lgrp_enter())
3939fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (SMB_LGRP_OFFLINE);
3949fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
395148c5f43SAlan Wright 	if (getgrnam(new_gname) == NULL) {
396148c5f43SAlan Wright 		if (smb_lgrp_pgrp_add(new_gname) != 0) {
397148c5f43SAlan Wright 			smb_lgrp_exit();
398148c5f43SAlan Wright 			return (SMB_LGRP_POSIXCREATE_FAILED);
399148c5f43SAlan Wright 		}
400148c5f43SAlan Wright 
401148c5f43SAlan Wright 		if (getgrnam(new_gname) == NULL) {
402148c5f43SAlan Wright 			smb_lgrp_exit();
403148c5f43SAlan Wright 			return (SMB_LGRP_NOT_FOUND);
404148c5f43SAlan Wright 		}
405148c5f43SAlan Wright 	}
406148c5f43SAlan Wright 
407dc20a302Sas200622 	db = smb_lgrp_db_open(SMB_LGRP_DB_ORW);
408dc20a302Sas200622 	rc = smb_lgrp_gtbl_update(db, gname, &grp, SMB_LGRP_GTBL_NAME);
409dc20a302Sas200622 	smb_lgrp_db_close(db);
410dc20a302Sas200622 
4119fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_lgrp_exit();
412dc20a302Sas200622 	return (rc);
413dc20a302Sas200622 }
414dc20a302Sas200622 
415dc20a302Sas200622 /*
416dc20a302Sas200622  * smb_lgrp_delete
417dc20a302Sas200622  *
418dc20a302Sas200622  * Deletes the specified local group.
419dc20a302Sas200622  */
420dc20a302Sas200622 int
421dc20a302Sas200622 smb_lgrp_delete(char *gname)
422dc20a302Sas200622 {
423dc20a302Sas200622 	sqlite *db;
424dc20a302Sas200622 	int rc;
425dc20a302Sas200622 
426fe1c642dSBill Krier 	if (!smb_lgrp_normalize_name(gname))
427dc20a302Sas200622 		return (SMB_LGRP_INVALID_NAME);
428dc20a302Sas200622 
429dc20a302Sas200622 	/* Cannot remove a built-in group */
4307f667e74Sjose borrego 	if (smb_wka_lookup_name(gname) != NULL)
431dc20a302Sas200622 		return (SMB_LGRP_WKSID);
432dc20a302Sas200622 
43396a62adaSjoyce mcintosh 
43496a62adaSjoyce mcintosh 	if (!smb_lgrp_exists(gname))
43596a62adaSjoyce mcintosh 		return (SMB_LGRP_NOT_FOUND);
43696a62adaSjoyce mcintosh 
4379fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (!smb_lgrp_enter())
4389fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (SMB_LGRP_OFFLINE);
4399fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
440dc20a302Sas200622 	db = smb_lgrp_db_open(SMB_LGRP_DB_ORW);
441dc20a302Sas200622 	rc = smb_lgrp_gtbl_delete(db, gname);
442dc20a302Sas200622 	smb_lgrp_db_close(db);
443dc20a302Sas200622 
4449fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_lgrp_exit();
445dc20a302Sas200622 	return (rc);
446dc20a302Sas200622 }
447dc20a302Sas200622 
448dc20a302Sas200622 /*
449dc20a302Sas200622  * smb_lgrp_setcmnt
450dc20a302Sas200622  *
451dc20a302Sas200622  * Sets the description for the given group
452dc20a302Sas200622  */
453dc20a302Sas200622 int
454dc20a302Sas200622 smb_lgrp_setcmnt(char *gname, char *cmnt)
455dc20a302Sas200622 {
456dc20a302Sas200622 	smb_group_t grp;
457dc20a302Sas200622 	sqlite *db;
458dc20a302Sas200622 	int rc;
459dc20a302Sas200622 
460fe1c642dSBill Krier 	if (!smb_lgrp_normalize_name(gname))
461dc20a302Sas200622 		return (SMB_LGRP_INVALID_NAME);
462dc20a302Sas200622 
463dc20a302Sas200622 	if (cmnt && (strlen(cmnt) > SMB_LGRP_COMMENT_MAX))
464dc20a302Sas200622 		return (SMB_LGRP_INVALID_ARG);
465dc20a302Sas200622 
466dc20a302Sas200622 	grp.sg_cmnt = cmnt;
467dc20a302Sas200622 
4689fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (!smb_lgrp_enter())
4699fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (SMB_LGRP_OFFLINE);
4709fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
471dc20a302Sas200622 	db = smb_lgrp_db_open(SMB_LGRP_DB_ORW);
472dc20a302Sas200622 	rc = smb_lgrp_gtbl_update(db, gname, &grp, SMB_LGRP_GTBL_CMNT);
473dc20a302Sas200622 	smb_lgrp_db_close(db);
474dc20a302Sas200622 
4759fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_lgrp_exit();
476dc20a302Sas200622 	return (rc);
477dc20a302Sas200622 }
478dc20a302Sas200622 
479dc20a302Sas200622 /*
480dc20a302Sas200622  * smb_lgrp_getcmnt
481dc20a302Sas200622  *
482dc20a302Sas200622  * Obtain the description of the specified group
483dc20a302Sas200622  */
484dc20a302Sas200622 int
485dc20a302Sas200622 smb_lgrp_getcmnt(char *gname, char **cmnt)
486dc20a302Sas200622 {
487dc20a302Sas200622 	smb_group_t grp;
488dc20a302Sas200622 	sqlite *db;
489dc20a302Sas200622 	int rc;
490dc20a302Sas200622 
491fe1c642dSBill Krier 	if (!smb_lgrp_normalize_name(gname))
492dc20a302Sas200622 		return (SMB_LGRP_INVALID_NAME);
493dc20a302Sas200622 
494dc20a302Sas200622 	if (cmnt == NULL)
495dc20a302Sas200622 		return (SMB_LGRP_INVALID_ARG);
496dc20a302Sas200622 
4979fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (!smb_lgrp_enter())
4989fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (SMB_LGRP_OFFLINE);
4999fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
500dc20a302Sas200622 	db = smb_lgrp_db_open(SMB_LGRP_DB_ORD);
501dc20a302Sas200622 	rc = smb_lgrp_gtbl_lookup(db, SMB_LGRP_GTBL_NAME, &grp,
502dc20a302Sas200622 	    SMB_LGRP_INFO_CMNT, gname);
503dc20a302Sas200622 	smb_lgrp_db_close(db);
5049fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_lgrp_exit();
505dc20a302Sas200622 
506dc20a302Sas200622 	if (rc == SMB_LGRP_SUCCESS) {
507dc20a302Sas200622 		*cmnt = grp.sg_cmnt;
508dc20a302Sas200622 		grp.sg_cmnt = NULL;
509dc20a302Sas200622 		smb_lgrp_free(&grp);
510dc20a302Sas200622 	}
511dc20a302Sas200622 
512dc20a302Sas200622 	return (rc);
513dc20a302Sas200622 }
514dc20a302Sas200622 
515dc20a302Sas200622 
516dc20a302Sas200622 /*
517dc20a302Sas200622  * smb_lgrp_setpriv
518dc20a302Sas200622  *
519dc20a302Sas200622  * Enable/disable the specified privilge for the group
520dc20a302Sas200622  */
521dc20a302Sas200622 int
522dc20a302Sas200622 smb_lgrp_setpriv(char *gname, uint8_t priv_lid, boolean_t enable)
523dc20a302Sas200622 {
524dc20a302Sas200622 	sqlite *db;
525dc20a302Sas200622 	int rc;
526dc20a302Sas200622 
527fe1c642dSBill Krier 	if (!smb_lgrp_normalize_name(gname))
528dc20a302Sas200622 		return (SMB_LGRP_INVALID_NAME);
529dc20a302Sas200622 
530dc20a302Sas200622 	if ((priv_lid < SE_MIN_LUID) || (priv_lid > SE_MAX_LUID))
531dc20a302Sas200622 		return (SMB_LGRP_NO_SUCH_PRIV);
532dc20a302Sas200622 
5339fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (!smb_lgrp_enter())
5349fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (SMB_LGRP_OFFLINE);
5359fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
536dc20a302Sas200622 	db = smb_lgrp_db_open(SMB_LGRP_DB_ORW);
537dc20a302Sas200622 	rc = smb_lgrp_gtbl_update_plist(db, gname, priv_lid, enable);
538dc20a302Sas200622 	smb_lgrp_db_close(db);
5399fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_lgrp_exit();
540dc20a302Sas200622 
541dc20a302Sas200622 	if (enable) {
542dc20a302Sas200622 		if (rc == SMB_LGRP_PRIV_HELD)
543dc20a302Sas200622 			rc = SMB_LGRP_SUCCESS;
544dc20a302Sas200622 	} else {
545dc20a302Sas200622 		if (rc == SMB_LGRP_PRIV_NOT_HELD)
546dc20a302Sas200622 			rc = SMB_LGRP_SUCCESS;
547dc20a302Sas200622 	}
548dc20a302Sas200622 
549dc20a302Sas200622 	return (rc);
550dc20a302Sas200622 }
551dc20a302Sas200622 
552dc20a302Sas200622 /*
553dc20a302Sas200622  * smb_lgrp_getpriv
554dc20a302Sas200622  *
555dc20a302Sas200622  * Obtain the status of the specified privilge for the group
556dc20a302Sas200622  */
557dc20a302Sas200622 int
558dc20a302Sas200622 smb_lgrp_getpriv(char *gname, uint8_t priv_lid, boolean_t *enable)
559dc20a302Sas200622 {
560dc20a302Sas200622 	sqlite *db;
561dc20a302Sas200622 	smb_group_t grp;
562dc20a302Sas200622 	int rc;
563dc20a302Sas200622 
564fe1c642dSBill Krier 	if (!smb_lgrp_normalize_name(gname))
565dc20a302Sas200622 		return (SMB_LGRP_INVALID_NAME);
566dc20a302Sas200622 
567dc20a302Sas200622 	if ((priv_lid < SE_MIN_LUID) || (priv_lid > SE_MAX_LUID))
568dc20a302Sas200622 		return (SMB_LGRP_NO_SUCH_PRIV);
569dc20a302Sas200622 
5709fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (!smb_lgrp_enter())
5719fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (SMB_LGRP_OFFLINE);
5729fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
573dc20a302Sas200622 	db = smb_lgrp_db_open(SMB_LGRP_DB_ORD);
574dc20a302Sas200622 	rc = smb_lgrp_gtbl_lookup(db, SMB_LGRP_GTBL_NAME, &grp,
575dc20a302Sas200622 	    SMB_LGRP_INFO_PRIV, gname);
576dc20a302Sas200622 	smb_lgrp_db_close(db);
5779fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_lgrp_exit();
578dc20a302Sas200622 
579dc20a302Sas200622 	if (rc == SMB_LGRP_SUCCESS) {
580dc20a302Sas200622 		*enable = (smb_privset_query(grp.sg_privs, priv_lid) == 1);
581dc20a302Sas200622 		smb_lgrp_free(&grp);
582dc20a302Sas200622 	}
583dc20a302Sas200622 
584dc20a302Sas200622 	return (rc);
585dc20a302Sas200622 }
586dc20a302Sas200622 
587dc20a302Sas200622 /*
588dc20a302Sas200622  * smb_lgrp_add_member
589dc20a302Sas200622  *
590dc20a302Sas200622  * Add the given account to the specified group as its member.
591dc20a302Sas200622  */
592dc20a302Sas200622 int
5936537f381Sas200622 smb_lgrp_add_member(char *gname, smb_sid_t *msid, uint16_t sid_type)
594dc20a302Sas200622 {
595dc20a302Sas200622 	sqlite *db;
596dc20a302Sas200622 	smb_gsid_t mid;
597dc20a302Sas200622 	int rc;
598dc20a302Sas200622 
599fe1c642dSBill Krier 	if (!smb_lgrp_normalize_name(gname))
600dc20a302Sas200622 		return (SMB_LGRP_INVALID_NAME);
601dc20a302Sas200622 
6026537f381Sas200622 	if (!smb_sid_isvalid(msid))
603dc20a302Sas200622 		return (SMB_LGRP_INVALID_ARG);
604dc20a302Sas200622 
605dc20a302Sas200622 	if (!smb_lgrp_chkmember(sid_type))
606dc20a302Sas200622 		return (SMB_LGRP_INVALID_MEMBER);
607dc20a302Sas200622 
608dc20a302Sas200622 	mid.gs_sid = msid;
609dc20a302Sas200622 	mid.gs_type = sid_type;
610dc20a302Sas200622 
6119fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (!smb_lgrp_enter())
6129fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (SMB_LGRP_OFFLINE);
6139fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
614dc20a302Sas200622 	db = smb_lgrp_db_open(SMB_LGRP_DB_ORW);
615dc20a302Sas200622 	rc = smb_lgrp_gtbl_update_mlist(db, gname, &mid, SMB_LGRP_DB_ADDMEMBER);
616dc20a302Sas200622 	smb_lgrp_db_close(db);
617dc20a302Sas200622 
6189fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_lgrp_exit();
619dc20a302Sas200622 	return (rc);
620dc20a302Sas200622 }
621dc20a302Sas200622 
622dc20a302Sas200622 /*
623dc20a302Sas200622  * smb_lgrp_del_member
624dc20a302Sas200622  *
625dc20a302Sas200622  * Delete the specified member from the given group.
626dc20a302Sas200622  */
627dc20a302Sas200622 int
6286537f381Sas200622 smb_lgrp_del_member(char *gname, smb_sid_t *msid, uint16_t sid_type)
629dc20a302Sas200622 {
630dc20a302Sas200622 	sqlite *db;
631dc20a302Sas200622 	smb_gsid_t mid;
632dc20a302Sas200622 	int rc;
633dc20a302Sas200622 
634fe1c642dSBill Krier 	if (!smb_lgrp_normalize_name(gname))
635dc20a302Sas200622 		return (SMB_LGRP_INVALID_NAME);
636dc20a302Sas200622 
6376537f381Sas200622 	if (!smb_sid_isvalid(msid))
638dc20a302Sas200622 		return (SMB_LGRP_INVALID_ARG);
639dc20a302Sas200622 
640dc20a302Sas200622 	mid.gs_sid = msid;
641dc20a302Sas200622 	mid.gs_type = sid_type;
642dc20a302Sas200622 
6439fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (!smb_lgrp_enter())
6449fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (SMB_LGRP_OFFLINE);
6459fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
646dc20a302Sas200622 	db = smb_lgrp_db_open(SMB_LGRP_DB_ORW);
647dc20a302Sas200622 	rc = smb_lgrp_gtbl_update_mlist(db, gname, &mid, SMB_LGRP_DB_DELMEMBER);
648dc20a302Sas200622 	smb_lgrp_db_close(db);
649dc20a302Sas200622 
6509fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_lgrp_exit();
651dc20a302Sas200622 	return (rc);
652dc20a302Sas200622 }
653dc20a302Sas200622 
654dc20a302Sas200622 /*
655dc20a302Sas200622  * smb_lgrp_getbyname
656dc20a302Sas200622  *
657dc20a302Sas200622  * Retrieves the information of the group specified by
658dc20a302Sas200622  * the given name.
659dc20a302Sas200622  *
660dc20a302Sas200622  * Note that this function doesn't allocate the group
661dc20a302Sas200622  * structure itself only the fields, so the given grp
662dc20a302Sas200622  * pointer has to point to a group structure.
663dc20a302Sas200622  * Caller must free the allocated memories for the fields
664dc20a302Sas200622  * by calling smb_lgrp_free().
665dc20a302Sas200622  */
666dc20a302Sas200622 int
667dc20a302Sas200622 smb_lgrp_getbyname(char *gname, smb_group_t *grp)
668dc20a302Sas200622 {
669dc20a302Sas200622 	sqlite *db;
670dc20a302Sas200622 	int rc;
671dc20a302Sas200622 
672fe1c642dSBill Krier 	if (!smb_lgrp_normalize_name(gname))
673dc20a302Sas200622 		return (SMB_LGRP_INVALID_NAME);
674dc20a302Sas200622 
6759fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (!smb_lgrp_enter())
6769fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (SMB_LGRP_OFFLINE);
6779fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
678dc20a302Sas200622 	db = smb_lgrp_db_open(SMB_LGRP_DB_ORD);
679dc20a302Sas200622 	rc = smb_lgrp_gtbl_lookup(db, SMB_LGRP_GTBL_NAME, grp,
680dc20a302Sas200622 	    SMB_LGRP_INFO_ALL, gname);
681dc20a302Sas200622 	smb_lgrp_db_close(db);
682dc20a302Sas200622 
6839fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_lgrp_exit();
684dc20a302Sas200622 	return (rc);
685dc20a302Sas200622 }
686dc20a302Sas200622 
687dc20a302Sas200622 /*
688dc20a302Sas200622  * smb_lgrp_getbyrid
689dc20a302Sas200622  *
690dc20a302Sas200622  * Retrieves the information of the group specified by
691dc20a302Sas200622  * the given RID and domain type.
692dc20a302Sas200622  *
693dc20a302Sas200622  * Note that this function doesn't allocate the group
694dc20a302Sas200622  * structure itself only the fields, so the given grp
695dc20a302Sas200622  * pointer has to point to a group structure.
696dc20a302Sas200622  * Caller must free the allocated memories for the fields
697dc20a302Sas200622  * by calling smb_lgrp_free().
698dc20a302Sas200622  *
699dc20a302Sas200622  * If grp is NULL no information would be returned. The
700dc20a302Sas200622  * return value of SMB_LGRP_SUCCESS will indicate that a
701dc20a302Sas200622  * group with the given information exists.
702dc20a302Sas200622  */
703dc20a302Sas200622 int
7049fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_lgrp_getbyrid(uint32_t rid, smb_domain_type_t domtype, smb_group_t *grp)
705dc20a302Sas200622 {
706dc20a302Sas200622 	smb_group_t tmpgrp;
707dc20a302Sas200622 	sqlite *db;
708dc20a302Sas200622 	int infolvl = SMB_LGRP_INFO_ALL;
709dc20a302Sas200622 	int rc;
710dc20a302Sas200622 
7119fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (!smb_lgrp_enter())
7129fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (SMB_LGRP_OFFLINE);
7139fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
714dc20a302Sas200622 	if (grp == NULL) {
715dc20a302Sas200622 		grp = &tmpgrp;
716dc20a302Sas200622 		infolvl = SMB_LGRP_INFO_NONE;
717dc20a302Sas200622 	}
718dc20a302Sas200622 
719dc20a302Sas200622 	db = smb_lgrp_db_open(SMB_LGRP_DB_ORD);
720dc20a302Sas200622 	rc = smb_lgrp_gtbl_lookup(db, SMB_LGRP_GTBL_SIDRID, grp, infolvl,
721dc20a302Sas200622 	    rid, domtype);
722dc20a302Sas200622 	smb_lgrp_db_close(db);
723dc20a302Sas200622 
7249fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_lgrp_exit();
725dc20a302Sas200622 	return (rc);
726dc20a302Sas200622 }
727dc20a302Sas200622 
728dc20a302Sas200622 /*
729dc20a302Sas200622  * smb_lgrp_numbydomain
730dc20a302Sas200622  *
731dc20a302Sas200622  * Returns the number of groups in the given domain in the
732dc20a302Sas200622  * arg 'count'
733dc20a302Sas200622  */
734dc20a302Sas200622 int
7359fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_lgrp_numbydomain(smb_domain_type_t dom_type, int *count)
736dc20a302Sas200622 {
737dc20a302Sas200622 	sqlite *db;
738dc20a302Sas200622 	int dom_idx;
739dc20a302Sas200622 	int rc;
740dc20a302Sas200622 
741dc20a302Sas200622 	switch (dom_type) {
7429fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	case SMB_DOMAIN_LOCAL:
743dc20a302Sas200622 		dom_idx = SMB_LGRP_LOCAL_IDX;
744dc20a302Sas200622 		break;
7459fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	case SMB_DOMAIN_BUILTIN:
746dc20a302Sas200622 		dom_idx = SMB_LGRP_BUILTIN_IDX;
747dc20a302Sas200622 		break;
748dc20a302Sas200622 	default:
749dc20a302Sas200622 		*count = 0;
750dc20a302Sas200622 		return (SMB_LGRP_INVALID_ARG);
751dc20a302Sas200622 	}
752dc20a302Sas200622 
7539fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (!smb_lgrp_enter())
7549fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (SMB_LGRP_OFFLINE);
7559fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
756dc20a302Sas200622 	db = smb_lgrp_db_open(SMB_LGRP_DB_ORD);
757dc20a302Sas200622 	rc = smb_lgrp_gtbl_count(db, dom_idx, count);
758dc20a302Sas200622 	smb_lgrp_db_close(db);
759dc20a302Sas200622 
7609fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_lgrp_exit();
761dc20a302Sas200622 	return (rc);
762dc20a302Sas200622 }
763dc20a302Sas200622 
764dc20a302Sas200622 /*
765dc20a302Sas200622  * smb_lgrp_free
766dc20a302Sas200622  *
767dc20a302Sas200622  * Frees the allocated memory for the fields of the given
768dc20a302Sas200622  * group structure. Note that this function doesn't free
769dc20a302Sas200622  * the group itself.
770dc20a302Sas200622  */
771dc20a302Sas200622 void
772dc20a302Sas200622 smb_lgrp_free(smb_group_t *grp)
773dc20a302Sas200622 {
774dc20a302Sas200622 	int i;
775dc20a302Sas200622 
776dc20a302Sas200622 	if (grp == NULL)
777dc20a302Sas200622 		return;
778dc20a302Sas200622 
779dc20a302Sas200622 	free(grp->sg_name);
780dc20a302Sas200622 	free(grp->sg_cmnt);
7816537f381Sas200622 	smb_sid_free(grp->sg_id.gs_sid);
782dc20a302Sas200622 	smb_privset_free(grp->sg_privs);
783dc20a302Sas200622 
784dc20a302Sas200622 	for (i = 0; i < grp->sg_nmembers; i++)
7856537f381Sas200622 		smb_sid_free(grp->sg_members[i].gs_sid);
786dc20a302Sas200622 	free(grp->sg_members);
787dc20a302Sas200622 }
788dc20a302Sas200622 
789dc20a302Sas200622 /*
790dc20a302Sas200622  * smb_lgrp_iteropen
791dc20a302Sas200622  *
792dc20a302Sas200622  * Initializes the given group iterator by opening
793dc20a302Sas200622  * the group database and creating a virtual machine
794dc20a302Sas200622  * for iteration.
795dc20a302Sas200622  */
796dc20a302Sas200622 int
797dc20a302Sas200622 smb_lgrp_iteropen(smb_giter_t *iter)
798dc20a302Sas200622 {
799dc20a302Sas200622 	char *sql;
800dc20a302Sas200622 	char *errmsg = NULL;
801dc20a302Sas200622 	int rc = SMB_LGRP_SUCCESS;
802dc20a302Sas200622 
803dc20a302Sas200622 	assert(iter);
804dc20a302Sas200622 
8059fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (!smb_lgrp_enter())
8069fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (SMB_LGRP_OFFLINE);
8079fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
808dc20a302Sas200622 	bzero(iter, sizeof (smb_giter_t));
809dc20a302Sas200622 
810dc20a302Sas200622 	sql = sqlite_mprintf("SELECT * FROM groups");
8119fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (sql == NULL) {
8129fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		smb_lgrp_exit();
813dc20a302Sas200622 		return (SMB_LGRP_NO_MEMORY);
8149fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
815dc20a302Sas200622 
816dc20a302Sas200622 	iter->sgi_db = smb_lgrp_db_open(SMB_LGRP_DB_ORD);
817dc20a302Sas200622 	if (iter->sgi_db == NULL) {
818dc20a302Sas200622 		sqlite_freemem(sql);
8199fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		smb_lgrp_exit();
820dc20a302Sas200622 		return (SMB_LGRP_DBOPEN_FAILED);
821dc20a302Sas200622 	}
822dc20a302Sas200622 
823dc20a302Sas200622 	rc = sqlite_compile(iter->sgi_db, sql, NULL, &iter->sgi_vm, &errmsg);
824dc20a302Sas200622 	sqlite_freemem(sql);
825dc20a302Sas200622 
826dc20a302Sas200622 	if (rc != SQLITE_OK) {
827dc20a302Sas200622 		syslog(LOG_DEBUG, "failed to create a VM (%s)",
828dc20a302Sas200622 		    NULL_MSGCHK(errmsg));
829dc20a302Sas200622 		rc = SMB_LGRP_DB_ERROR;
830dc20a302Sas200622 	}
831dc20a302Sas200622 
8329fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_lgrp_exit();
833dc20a302Sas200622 	return (rc);
834dc20a302Sas200622 }
835dc20a302Sas200622 
836dc20a302Sas200622 /*
837dc20a302Sas200622  * smb_lgrp_iterclose
838dc20a302Sas200622  *
839dc20a302Sas200622  * Closes the given group iterator.
840dc20a302Sas200622  */
841dc20a302Sas200622 void
842dc20a302Sas200622 smb_lgrp_iterclose(smb_giter_t *iter)
843dc20a302Sas200622 {
844dc20a302Sas200622 	char *errmsg = NULL;
845dc20a302Sas200622 	int rc;
846dc20a302Sas200622 
847dc20a302Sas200622 	assert(iter);
848dc20a302Sas200622 
8499fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (!smb_lgrp_enter())
8509fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return;
8519fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
852dc20a302Sas200622 	rc = sqlite_finalize(iter->sgi_vm, &errmsg);
853dc20a302Sas200622 	if (rc != SQLITE_OK) {
854dc20a302Sas200622 		syslog(LOG_DEBUG, "failed to destroy a VM (%s)",
855dc20a302Sas200622 		    NULL_MSGCHK(errmsg));
856dc20a302Sas200622 	}
857dc20a302Sas200622 
858dc20a302Sas200622 	smb_lgrp_db_close(iter->sgi_db);
8599fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_lgrp_exit();
8609fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
8619fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
8629fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
8639fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Returns B_TRUE if there has been an error during
8649fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * iteration.
8659fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
8669fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States boolean_t
8679fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_lgrp_itererror(smb_giter_t *iter)
8689fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
8699fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (iter->sgi_nerr != 0);
870dc20a302Sas200622 }
871dc20a302Sas200622 
872dc20a302Sas200622 /*
873dc20a302Sas200622  * smb_lgrp_iterate
874dc20a302Sas200622  *
875dc20a302Sas200622  * Iterate through group database
876dc20a302Sas200622  * Group information is returned in provided group structure.
877dc20a302Sas200622  *
878dc20a302Sas200622  * Note that this function doesn't allocate the group
879dc20a302Sas200622  * structure itself only the fields, so the given grp
880dc20a302Sas200622  * pointer has to point to a group structure.
881dc20a302Sas200622  * Caller must free the allocated memories for the fields
882dc20a302Sas200622  * by calling smb_lgrp_free().
883dc20a302Sas200622  */
884dc20a302Sas200622 int
885dc20a302Sas200622 smb_lgrp_iterate(smb_giter_t *iter, smb_group_t *grp)
886dc20a302Sas200622 {
887dc20a302Sas200622 	const char **values;
888dc20a302Sas200622 	int ncol;
889dc20a302Sas200622 	int rc;
890dc20a302Sas200622 	int i;
891dc20a302Sas200622 
892dc20a302Sas200622 	if (iter->sgi_vm == NULL || iter->sgi_db == NULL)
893dc20a302Sas200622 		return (SMB_LGRP_INVALID_ARG);
894dc20a302Sas200622 
8959fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (!smb_lgrp_enter())
8969fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (SMB_LGRP_OFFLINE);
8979fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
8989fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	for (;;) {
899dc20a302Sas200622 		bzero(grp, sizeof (smb_group_t));
900dc20a302Sas200622 		rc = sqlite_step(iter->sgi_vm, &ncol, &values, NULL);
9019fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		if (rc == SQLITE_DONE) {
9029fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			smb_lgrp_exit();
903dc20a302Sas200622 			return (SMB_LGRP_NO_MORE);
9049fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		}
905dc20a302Sas200622 
9069fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		if (rc != SQLITE_ROW) {
9079fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			smb_lgrp_exit();
908dc20a302Sas200622 			return (SMB_LGRP_DBEXEC_FAILED);
9099fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		}
910dc20a302Sas200622 
9119fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		if (ncol != SMB_LGRP_GTBL_NCOL) {
9129fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			smb_lgrp_exit();
913dc20a302Sas200622 			return (SMB_LGRP_DB_ERROR);
914dc20a302Sas200622 		}
915dc20a302Sas200622 
9169fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		for (i = 0; i < ncol; i++) {
9179fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			if (values[i] == NULL) {
9189fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 				smb_lgrp_exit();
9199fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 				return (SMB_LGRP_DB_ERROR);
9209fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			}
9219fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		}
9229fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
9239fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		rc = smb_lgrp_decode(grp, (char **)values, SMB_LGRP_INFO_ALL,
9249fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		    iter->sgi_db);
9259fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		if (rc == SMB_LGRP_SUCCESS)
9269fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			break;
9279fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
9289fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		iter->sgi_nerr++;
9299fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		syslog(LOG_ERR, "smb_lgrp_iterate: %s", smb_lgrp_strerror(rc));
9309fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
9319fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
9329fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_lgrp_exit();
9339fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (rc);
9349fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
935dc20a302Sas200622 }
936dc20a302Sas200622 
937dc20a302Sas200622 /*
938dc20a302Sas200622  * smb_lgrp_is_member
939dc20a302Sas200622  *
940dc20a302Sas200622  * Check to see if the specified account is a member of
941dc20a302Sas200622  * the given group.
942dc20a302Sas200622  */
943dc20a302Sas200622 boolean_t
9446537f381Sas200622 smb_lgrp_is_member(smb_group_t *grp, smb_sid_t *sid)
945dc20a302Sas200622 {
946dc20a302Sas200622 	int i;
947dc20a302Sas200622 
948dc20a302Sas200622 	if (grp == NULL || grp->sg_members == NULL || sid == NULL)
949dc20a302Sas200622 		return (B_FALSE);
950dc20a302Sas200622 
951dc20a302Sas200622 	for (i = 0; i < grp->sg_nmembers; i++) {
9526537f381Sas200622 		if (smb_sid_cmp(grp->sg_members[i].gs_sid, sid))
953dc20a302Sas200622 			return (B_TRUE);
954dc20a302Sas200622 	}
955dc20a302Sas200622 
956dc20a302Sas200622 	return (B_FALSE);
957dc20a302Sas200622 }
958dc20a302Sas200622 
959dc20a302Sas200622 /*
960dc20a302Sas200622  * smb_lgrp_strerror
961dc20a302Sas200622  *
962dc20a302Sas200622  * Returns a text for the given group error code.
963dc20a302Sas200622  */
964dc20a302Sas200622 char *
9659fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_lgrp_strerror(int errnum)
966dc20a302Sas200622 {
9679fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	int	i;
9689fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	int	nerr = (sizeof (errtab) / sizeof (errtab[0]));
9699fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
9709fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	for (i = 0; i < nerr; ++i) {
9719fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		if (errnum == errtab[i].errnum)
9729fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			return (errtab[i].errmsg);
973dc20a302Sas200622 	}
974dc20a302Sas200622 
9759fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return ("unknown local group error");
976dc20a302Sas200622 }
977dc20a302Sas200622 
978dc20a302Sas200622 /*
979c5866007SKeyur Desai  * smb_lgrp_err_to_ntstatus
980c5866007SKeyur Desai  *
981c5866007SKeyur Desai  * This routine maps Local group operation errors to NT Status error codes.
982c5866007SKeyur Desai  */
983c5866007SKeyur Desai uint32_t
984c5866007SKeyur Desai smb_lgrp_err_to_ntstatus(uint32_t lgrp_err)
985c5866007SKeyur Desai {
986c5866007SKeyur Desai 	int i;
987c5866007SKeyur Desai 	static struct err_map {
988c5866007SKeyur Desai 		uint32_t lgrp_err;
989c5866007SKeyur Desai 		uint32_t nt_status;
990c5866007SKeyur Desai 	} err_map[] = {
991c5866007SKeyur Desai 		{ SMB_LGRP_SUCCESS,		NT_STATUS_SUCCESS },
992c5866007SKeyur Desai 		{ SMB_LGRP_INVALID_ARG,		NT_STATUS_INVALID_PARAMETER },
993c5866007SKeyur Desai 		{ SMB_LGRP_INVALID_MEMBER,	NT_STATUS_INVALID_MEMBER },
994c5866007SKeyur Desai 		{ SMB_LGRP_INVALID_NAME,	NT_STATUS_INVALID_PARAMETER },
995c5866007SKeyur Desai 		{ SMB_LGRP_NOT_FOUND,		NT_STATUS_NO_SUCH_ALIAS },
996c5866007SKeyur Desai 		{ SMB_LGRP_EXISTS,		NT_STATUS_ALIAS_EXISTS },
997c5866007SKeyur Desai 		{ SMB_LGRP_NO_SID,		NT_STATUS_INVALID_SID },
998c5866007SKeyur Desai 		{ SMB_LGRP_NO_LOCAL_SID,	NT_STATUS_INVALID_SID },
999c5866007SKeyur Desai 		{ SMB_LGRP_SID_NOTLOCAL,	NT_STATUS_INVALID_SID },
1000c5866007SKeyur Desai 		{ SMB_LGRP_WKSID,		NT_STATUS_INVALID_SID },
1001c5866007SKeyur Desai 		{ SMB_LGRP_NO_MEMORY,		NT_STATUS_NO_MEMORY },
1002c5866007SKeyur Desai 		{ SMB_LGRP_DB_ERROR,		NT_STATUS_INTERNAL_DB_ERROR },
1003c5866007SKeyur Desai 		{ SMB_LGRP_DBINIT_ERROR,	NT_STATUS_INTERNAL_DB_ERROR },
1004c5866007SKeyur Desai 		{ SMB_LGRP_INTERNAL_ERROR,	NT_STATUS_INTERNAL_ERROR },
1005c5866007SKeyur Desai 		{ SMB_LGRP_MEMBER_IN_GROUP,	NT_STATUS_MEMBER_IN_ALIAS },
1006c5866007SKeyur Desai 		{ SMB_LGRP_MEMBER_NOT_IN_GROUP,	NT_STATUS_MEMBER_NOT_IN_ALIAS },
1007c5866007SKeyur Desai 		{ SMB_LGRP_NO_SUCH_PRIV,	NT_STATUS_NO_SUCH_PRIVILEGE },
1008c5866007SKeyur Desai 		{ SMB_LGRP_NO_SUCH_DOMAIN,	NT_STATUS_NO_SUCH_DOMAIN },
1009c5866007SKeyur Desai 		{ SMB_LGRP_PRIV_HELD,		NT_STATUS_SUCCESS },
1010c5866007SKeyur Desai 		{ SMB_LGRP_PRIV_NOT_HELD,	NT_STATUS_PRIVILEGE_NOT_HELD },
1011c5866007SKeyur Desai 		{ SMB_LGRP_BAD_DATA,		NT_STATUS_DATA_ERROR },
1012148c5f43SAlan Wright 		{ SMB_LGRP_NO_MORE,		NT_STATUS_NO_MORE_ENTRIES },
1013c5866007SKeyur Desai 		{ SMB_LGRP_DBOPEN_FAILED,	NT_STATUS_INTERNAL_DB_ERROR },
1014c5866007SKeyur Desai 		{ SMB_LGRP_DBEXEC_FAILED,	NT_STATUS_INTERNAL_DB_ERROR },
1015c5866007SKeyur Desai 		{ SMB_LGRP_DBINIT_FAILED,	NT_STATUS_INTERNAL_DB_ERROR },
1016c5866007SKeyur Desai 		{ SMB_LGRP_DOMLKP_FAILED,	NT_STATUS_INTERNAL_DB_ERROR },
1017c5866007SKeyur Desai 		{ SMB_LGRP_DOMINS_FAILED,	NT_STATUS_INTERNAL_DB_ERROR },
1018c5866007SKeyur Desai 		{ SMB_LGRP_INSERT_FAILED,	NT_STATUS_INTERNAL_DB_ERROR },
1019c5866007SKeyur Desai 		{ SMB_LGRP_DELETE_FAILED,	NT_STATUS_INTERNAL_DB_ERROR },
1020c5866007SKeyur Desai 		{ SMB_LGRP_UPDATE_FAILED,	NT_STATUS_INTERNAL_DB_ERROR },
1021c5866007SKeyur Desai 		{ SMB_LGRP_LOOKUP_FAILED,	NT_STATUS_INTERNAL_DB_ERROR },
1022c5866007SKeyur Desai 		{ SMB_LGRP_NOT_SUPPORTED,	NT_STATUS_NOT_SUPPORTED },
1023148c5f43SAlan Wright 		{ SMB_LGRP_OFFLINE,		NT_STATUS_INTERNAL_ERROR },
1024148c5f43SAlan Wright 		{ SMB_LGRP_POSIXCREATE_FAILED,	NT_STATUS_UNSUCCESSFUL }
1025c5866007SKeyur Desai 	};
1026c5866007SKeyur Desai 
1027c5866007SKeyur Desai 	for (i = 0; i < sizeof (err_map)/sizeof (err_map[0]); ++i) {
1028c5866007SKeyur Desai 		if (err_map[i].lgrp_err == lgrp_err)
1029c5866007SKeyur Desai 			return (err_map[i].nt_status);
1030c5866007SKeyur Desai 	}
1031c5866007SKeyur Desai 
1032c5866007SKeyur Desai 	return (NT_STATUS_INTERNAL_ERROR);
1033c5866007SKeyur Desai }
1034c5866007SKeyur Desai 
1035c5866007SKeyur Desai /*
1036dc20a302Sas200622  * smb_lgrp_chkmember
1037dc20a302Sas200622  *
1038dc20a302Sas200622  * Determines valid account types for being member of
103936a00406SGordon Ross  * a local group.  We really have no business trying to
104036a00406SGordon Ross  * keep track of the "type" of SIDs in a group, so just
104136a00406SGordon Ross  * validate that the SID type is a known enum value.
1042dc20a302Sas200622  */
1043dc20a302Sas200622 static boolean_t
1044dc20a302Sas200622 smb_lgrp_chkmember(uint16_t sid_type)
1045dc20a302Sas200622 {
104636a00406SGordon Ross 	switch (sid_type) {
104736a00406SGordon Ross 	case SidTypeNull:
104836a00406SGordon Ross 	case SidTypeUser:
104936a00406SGordon Ross 	case SidTypeGroup:
105036a00406SGordon Ross 	case SidTypeAlias:
105136a00406SGordon Ross 	case SidTypeWellKnownGroup:
105236a00406SGordon Ross 	case SidTypeDeletedAccount:
105336a00406SGordon Ross 	case SidTypeInvalid:
105436a00406SGordon Ross 	case SidTypeUnknown:
105536a00406SGordon Ross 		return (B_TRUE);
105636a00406SGordon Ross 	}
105736a00406SGordon Ross 	return (B_FALSE);
1058dc20a302Sas200622 }
1059dc20a302Sas200622 
1060dc20a302Sas200622 /*
1061dc20a302Sas200622  * smb_lgrp_start
1062dc20a302Sas200622  *
1063dc20a302Sas200622  * Initializes the library private global variables.
10649fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Create the database, if it doesn't exist, and add
10659fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * the predefined builtin groups.
1066dc20a302Sas200622  */
1067dc20a302Sas200622 int
1068dc20a302Sas200622 smb_lgrp_start(void)
1069dc20a302Sas200622 {
10709fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	static char	*builtin[] = {
10719fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		"Administrators",
10729fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		"Backup Operators",
10739fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		"Power Users"
10749fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	};
10756537f381Sas200622 	smb_wka_t	*wka;
10769fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	char		*localsid;
10779fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	int		i, rc;
10789fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	int		ngrp = sizeof (builtin) / sizeof (builtin[0]);
1079dc20a302Sas200622 
10809fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	(void) mutex_lock(&smb_localgrp.lg_mutex);
10819fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
10829fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if ((localsid = smb_config_get_localsid()) == NULL) {
10839fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		(void) mutex_unlock(&smb_localgrp.lg_mutex);
1084dc20a302Sas200622 		return (SMB_LGRP_NO_LOCAL_SID);
1085dc20a302Sas200622 	}
1086dc20a302Sas200622 
10879fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_localgrp.lg_machine_sid = smb_sid_fromstr(localsid);
10889fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	free(localsid);
10899fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
10909fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (!smb_sid_isvalid(smb_localgrp.lg_machine_sid)) {
10919fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		free(smb_localgrp.lg_machine_sid);
10929fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		smb_localgrp.lg_machine_sid = NULL;
10939fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		(void) mutex_unlock(&smb_localgrp.lg_mutex);
1094dc20a302Sas200622 		return (SMB_LGRP_NO_LOCAL_SID);
1095dc20a302Sas200622 	}
1096dc20a302Sas200622 
1097dc20a302Sas200622 	rc = smb_lgrp_db_init();
1098dc20a302Sas200622 	if (rc != SMB_LGRP_SUCCESS) {
10999fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		free(smb_localgrp.lg_machine_sid);
11009fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		smb_localgrp.lg_machine_sid = NULL;
11019fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		(void) mutex_unlock(&smb_localgrp.lg_mutex);
1102dc20a302Sas200622 		return (rc);
1103dc20a302Sas200622 	}
1104dc20a302Sas200622 
11059fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_localgrp.lg_online = B_TRUE;
11069fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	(void) mutex_unlock(&smb_localgrp.lg_mutex);
11079fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
1108dc20a302Sas200622 	for (i = 0; i < ngrp; i++) {
1109c28afb19SYuri Pankov 		char	*tname;
1110c28afb19SYuri Pankov 
11119fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		if ((wka = smb_wka_lookup_name(builtin[i])) == NULL)
1112dc20a302Sas200622 			continue;
11139fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
1114c28afb19SYuri Pankov 		if ((tname = strdup(wka->wka_name)) == NULL)
1115c28afb19SYuri Pankov 			return (SMB_LGRP_NO_MEMORY);
1116c28afb19SYuri Pankov 		if (!smb_lgrp_exists(tname)) {
1117c28afb19SYuri Pankov 			rc = smb_lgrp_add(tname, wka->wka_desc);
111829bd2886SAlan Wright 			if (rc != SMB_LGRP_SUCCESS) {
111929bd2886SAlan Wright 				syslog(LOG_DEBUG, "failed to add %s",
1120c28afb19SYuri Pankov 				    tname);
112129bd2886SAlan Wright 			}
112229bd2886SAlan Wright 		}
1123c28afb19SYuri Pankov 		free(tname);
1124dc20a302Sas200622 	}
1125dc20a302Sas200622 
1126dc20a302Sas200622 	return (SMB_LGRP_SUCCESS);
1127dc20a302Sas200622 }
1128dc20a302Sas200622 
1129dc20a302Sas200622 /*
1130dc20a302Sas200622  * smb_lgrp_stop
1131dc20a302Sas200622  *
1132dc20a302Sas200622  * Unintialize the library global private variables.
1133dc20a302Sas200622  */
1134dc20a302Sas200622 void
1135dc20a302Sas200622 smb_lgrp_stop(void)
1136dc20a302Sas200622 {
11379fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	(void) mutex_lock(&smb_localgrp.lg_mutex);
11389fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (!smb_localgrp.lg_online)
11399fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return;
11409fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
11419fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_localgrp.lg_online = B_FALSE;
11429fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
11439fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	while (smb_localgrp.lg_refcnt > 0)
11449fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		(void) cond_wait(&smb_localgrp.lg_cv, &smb_localgrp.lg_mutex);
11459fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
11469fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	free(smb_localgrp.lg_machine_sid);
11479fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_localgrp.lg_machine_sid = NULL;
11489fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	(void) mutex_unlock(&smb_localgrp.lg_mutex);
11499fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
11509fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
11519fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static boolean_t
11529fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_lgrp_enter(void)
11539fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
11549fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	boolean_t	status;
11559fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
11569fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	(void) mutex_lock(&smb_localgrp.lg_mutex);
11579fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
11589fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	status = smb_localgrp.lg_online;
11599fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
11609fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (smb_localgrp.lg_online)
11619fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		++smb_localgrp.lg_refcnt;
11629fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
11639fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	(void) mutex_unlock(&smb_localgrp.lg_mutex);
11649fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (status);
11659fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
11669fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
11679fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static void
11689fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_lgrp_exit(void)
11699fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
11709fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	(void) mutex_lock(&smb_localgrp.lg_mutex);
11719fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	assert(smb_localgrp.lg_refcnt > 0);
11729fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
11739fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if ((--smb_localgrp.lg_refcnt) == 0)
11749fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		(void) cond_signal(&smb_localgrp.lg_cv);
11759fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
11769fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	(void) mutex_unlock(&smb_localgrp.lg_mutex);
1177dc20a302Sas200622 }
1178dc20a302Sas200622 
1179dc20a302Sas200622 /*
1180dc20a302Sas200622  * smb_lgrp_db_open
1181dc20a302Sas200622  *
1182dc20a302Sas200622  * Opens group database with the given mode.
1183dc20a302Sas200622  */
1184dc20a302Sas200622 static sqlite *
1185dc20a302Sas200622 smb_lgrp_db_open(int mode)
1186dc20a302Sas200622 {
1187dc20a302Sas200622 	sqlite *db;
1188dc20a302Sas200622 	char *errmsg = NULL;
1189dc20a302Sas200622 
1190dc20a302Sas200622 	db = sqlite_open(SMB_LGRP_DB_NAME, mode, &errmsg);
1191dc20a302Sas200622 	if (db == NULL) {
1192dc20a302Sas200622 		syslog(LOG_ERR, "failed to open group database (%s)",
1193dc20a302Sas200622 		    NULL_MSGCHK(errmsg));
1194dc20a302Sas200622 		sqlite_freemem(errmsg);
1195dc20a302Sas200622 	}
1196dc20a302Sas200622 
1197dc20a302Sas200622 	return (db);
1198dc20a302Sas200622 }
1199dc20a302Sas200622 
1200dc20a302Sas200622 /*
1201dc20a302Sas200622  * smb_lgrp_db_close
1202dc20a302Sas200622  *
1203dc20a302Sas200622  * Closes the given database handle
1204dc20a302Sas200622  */
1205dc20a302Sas200622 static void
1206dc20a302Sas200622 smb_lgrp_db_close(sqlite *db)
1207dc20a302Sas200622 {
1208dc20a302Sas200622 	if (db) {
1209dc20a302Sas200622 		sqlite_close(db);
1210dc20a302Sas200622 	}
1211dc20a302Sas200622 }
1212dc20a302Sas200622 
1213dc20a302Sas200622 /*
1214dc20a302Sas200622  * smb_lgrp_db_init
1215dc20a302Sas200622  *
1216dc20a302Sas200622  * Creates the group database based on the defined SQL statement.
1217dc20a302Sas200622  * It also initializes db_info and domain tables.
1218dc20a302Sas200622  */
1219dc20a302Sas200622 static int
1220dc20a302Sas200622 smb_lgrp_db_init(void)
1221dc20a302Sas200622 {
1222dc20a302Sas200622 	int dbrc = SQLITE_OK;
1223dc20a302Sas200622 	int rc = SMB_LGRP_SUCCESS;
1224dc20a302Sas200622 	sqlite *db = NULL;
1225dc20a302Sas200622 	char *errmsg = NULL;
1226dc20a302Sas200622 
1227dc20a302Sas200622 	db = sqlite_open(SMB_LGRP_DB_NAME, 0600, &errmsg);
1228dc20a302Sas200622 	if (db == NULL) {
1229dc20a302Sas200622 		syslog(LOG_ERR, "failed to create group database (%s)",
1230dc20a302Sas200622 		    NULL_MSGCHK(errmsg));
1231dc20a302Sas200622 		sqlite_freemem(errmsg);
1232dc20a302Sas200622 		return (SMB_LGRP_DBOPEN_FAILED);
1233dc20a302Sas200622 	}
1234dc20a302Sas200622 
1235dc20a302Sas200622 	sqlite_busy_timeout(db, SMB_LGRP_DB_TIMEOUT);
1236dc20a302Sas200622 	dbrc = sqlite_exec(db, "BEGIN TRANSACTION;", NULL, NULL, &errmsg);
1237dc20a302Sas200622 	if (dbrc != SQLITE_OK) {
1238dc20a302Sas200622 		syslog(LOG_DEBUG, "failed to begin database transaction (%s)",
1239dc20a302Sas200622 		    NULL_MSGCHK(errmsg));
1240dc20a302Sas200622 		sqlite_freemem(errmsg);
1241dc20a302Sas200622 		sqlite_close(db);
1242dc20a302Sas200622 		return (SMB_LGRP_DBEXEC_FAILED);
1243dc20a302Sas200622 	}
1244dc20a302Sas200622 
1245dc20a302Sas200622 	switch (sqlite_exec(db, SMB_LGRP_DB_SQL, NULL, NULL, &errmsg)) {
1246dc20a302Sas200622 	case SQLITE_ERROR:
1247dc20a302Sas200622 		/*
1248dc20a302Sas200622 		 * This is the normal situation: CREATE probably failed because
1249dc20a302Sas200622 		 * tables already exist. It may indicate an error in SQL as well
1250dc20a302Sas200622 		 * but we cannot tell.
1251dc20a302Sas200622 		 */
1252dc20a302Sas200622 		sqlite_freemem(errmsg);
1253dc20a302Sas200622 		dbrc = sqlite_exec(db, "ROLLBACK TRANSACTION", NULL, NULL,
1254dc20a302Sas200622 		    &errmsg);
1255dc20a302Sas200622 		rc = SMB_LGRP_SUCCESS;
1256dc20a302Sas200622 		break;
1257dc20a302Sas200622 
1258dc20a302Sas200622 	case SQLITE_OK:
1259dc20a302Sas200622 		dbrc = sqlite_exec(db, "COMMIT TRANSACTION", NULL, NULL,
1260dc20a302Sas200622 		    &errmsg);
1261dc20a302Sas200622 		if (dbrc != SQLITE_OK)
1262dc20a302Sas200622 			break;
1263dc20a302Sas200622 		rc = smb_lgrp_dtbl_insert(db, NT_BUILTIN_DOMAIN_SIDSTR,
1264dc20a302Sas200622 		    NULL);
1265dc20a302Sas200622 		if (rc == SMB_LGRP_SUCCESS)
1266dc20a302Sas200622 			rc = smb_lgrp_db_setinfo(db);
1267dc20a302Sas200622 		if (rc != SMB_LGRP_SUCCESS) {
1268dc20a302Sas200622 			(void) sqlite_close(db);
1269dc20a302Sas200622 			(void) unlink(SMB_LGRP_DB_NAME);
1270dc20a302Sas200622 			return (rc);
1271dc20a302Sas200622 		}
1272dc20a302Sas200622 		break;
1273dc20a302Sas200622 
1274dc20a302Sas200622 	default:
1275dc20a302Sas200622 		syslog(LOG_ERR,
1276dc20a302Sas200622 		    "failed to initialize group database (%s)", errmsg);
1277dc20a302Sas200622 		sqlite_freemem(errmsg);
1278dc20a302Sas200622 		dbrc = sqlite_exec(db, "ROLLBACK TRANSACTION", NULL, NULL,
1279dc20a302Sas200622 		    &errmsg);
1280dc20a302Sas200622 		rc = SMB_LGRP_DBINIT_FAILED;
1281dc20a302Sas200622 		break;
1282dc20a302Sas200622 	}
1283dc20a302Sas200622 
1284dc20a302Sas200622 	if (dbrc != SQLITE_OK) {
1285dc20a302Sas200622 		/* this is bad - database may be left in a locked state */
1286dc20a302Sas200622 		syslog(LOG_DEBUG, "failed to close a transaction (%s)",
1287dc20a302Sas200622 		    NULL_MSGCHK(errmsg));
1288dc20a302Sas200622 		sqlite_freemem(errmsg);
1289dc20a302Sas200622 	}
1290dc20a302Sas200622 
1291dc20a302Sas200622 	(void) sqlite_close(db);
1292dc20a302Sas200622 	return (rc);
1293dc20a302Sas200622 }
1294dc20a302Sas200622 
1295dc20a302Sas200622 /*
1296dc20a302Sas200622  * smb_lgrp_gtbl_lookup
1297dc20a302Sas200622  *
1298dc20a302Sas200622  * This is a flexible lookup function for the group database.
1299dc20a302Sas200622  * The key type can be specified by the 'key' arg and the actual key
1300dc20a302Sas200622  * values can be passed after the 'infolvl' arg. 'infolvl' arg specifies
1301dc20a302Sas200622  * what information items for the specified group is needed.
1302dc20a302Sas200622  *
1303dc20a302Sas200622  * Note that the function assumes the given key is unique and only
1304dc20a302Sas200622  * specifies one or 0 group. The keys that are supported now are
1305dc20a302Sas200622  * the group name and the group SID
1306dc20a302Sas200622  *
1307dc20a302Sas200622  * Note that this function doesn't allocate the group
1308dc20a302Sas200622  * structure itself only the fields, so the given grp
1309dc20a302Sas200622  * pointer has to point to a group structure.
1310dc20a302Sas200622  * Caller must free the allocated memories for the fields
1311dc20a302Sas200622  * by calling smb_lgrp_free().
1312dc20a302Sas200622  */
1313dc20a302Sas200622 static int
1314dc20a302Sas200622 smb_lgrp_gtbl_lookup(sqlite *db, int key, smb_group_t *grp, int infolvl, ...)
1315dc20a302Sas200622 {
1316dc20a302Sas200622 	char *errmsg = NULL;
1317dc20a302Sas200622 	char *sql;
1318dc20a302Sas200622 	char **result;
1319dc20a302Sas200622 	int nrow, ncol;
1320dc20a302Sas200622 	int rc, dom_idx;
1321c8ec8eeaSjose borrego 	smb_group_t grpkey;
1322dc20a302Sas200622 	va_list ap;
1323dc20a302Sas200622 
1324dc20a302Sas200622 	if (db == NULL)
1325dc20a302Sas200622 		return (SMB_LGRP_DBOPEN_FAILED);
1326dc20a302Sas200622 
1327dc20a302Sas200622 	bzero(grp, sizeof (smb_group_t));
1328dc20a302Sas200622 	va_start(ap, infolvl);
1329dc20a302Sas200622 
1330dc20a302Sas200622 	switch (key) {
1331dc20a302Sas200622 	case SMB_LGRP_GTBL_NAME:
1332c8ec8eeaSjose borrego 		grpkey.sg_name = va_arg(ap, char *);
1333dc20a302Sas200622 		sql = sqlite_mprintf("SELECT * FROM groups WHERE name = '%s'",
1334c8ec8eeaSjose borrego 		    grpkey.sg_name);
1335dc20a302Sas200622 		break;
1336dc20a302Sas200622 
1337dc20a302Sas200622 	case SMB_LGRP_GTBL_SIDRID:
1338c8ec8eeaSjose borrego 		grpkey.sg_rid = va_arg(ap, uint32_t);
13399fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		grpkey.sg_domain = va_arg(ap, smb_domain_type_t);
13409fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		if (grpkey.sg_domain == SMB_DOMAIN_LOCAL) {
1341c8ec8eeaSjose borrego 			dom_idx = SMB_LGRP_LOCAL_IDX;
1342c8ec8eeaSjose borrego 			/* need to map the given rid to a gid */
1343c8ec8eeaSjose borrego 			rc = smb_lgrp_getgid(grpkey.sg_rid,
1344c8ec8eeaSjose borrego 			    (gid_t *)&grpkey.sg_rid);
1345c8ec8eeaSjose borrego 			if (rc != SMB_LGRP_SUCCESS) {
1346c8ec8eeaSjose borrego 				va_end(ap);
1347c8ec8eeaSjose borrego 				return (rc);
1348c8ec8eeaSjose borrego 			}
1349c8ec8eeaSjose borrego 		} else {
1350c8ec8eeaSjose borrego 			dom_idx = SMB_LGRP_BUILTIN_IDX;
1351c8ec8eeaSjose borrego 		}
1352c8ec8eeaSjose borrego 
1353dc20a302Sas200622 		sql = sqlite_mprintf("SELECT * FROM groups "
1354dc20a302Sas200622 		    "WHERE (sid_idx = %d) AND (sid_rid = %u)",
1355c8ec8eeaSjose borrego 		    dom_idx, grpkey.sg_rid);
1356dc20a302Sas200622 		break;
1357dc20a302Sas200622 
1358dc20a302Sas200622 	default:
1359dc20a302Sas200622 		va_end(ap);
1360dc20a302Sas200622 		return (SMB_LGRP_INVALID_ARG);
1361dc20a302Sas200622 	}
1362dc20a302Sas200622 
1363dc20a302Sas200622 	va_end(ap);
1364dc20a302Sas200622 	if (sql == NULL)
1365dc20a302Sas200622 		return (SMB_LGRP_NO_MEMORY);
1366dc20a302Sas200622 
1367dc20a302Sas200622 	rc = sqlite_get_table(db, sql, &result, &nrow, &ncol, &errmsg);
1368dc20a302Sas200622 	sqlite_freemem(sql);
1369dc20a302Sas200622 
1370dc20a302Sas200622 	if (rc != SQLITE_OK) {
1371dc20a302Sas200622 		syslog(LOG_DEBUG, "failed to lookup (%s)", NULL_MSGCHK(errmsg));
1372dc20a302Sas200622 		sqlite_freemem(errmsg);
1373dc20a302Sas200622 		return (SMB_LGRP_LOOKUP_FAILED);
1374dc20a302Sas200622 	}
1375dc20a302Sas200622 
1376dc20a302Sas200622 	if (nrow == 0)  {
1377dc20a302Sas200622 		/* group not found */
1378dc20a302Sas200622 		sqlite_free_table(result);
1379dc20a302Sas200622 		return (SMB_LGRP_NOT_FOUND);
1380dc20a302Sas200622 	}
1381dc20a302Sas200622 
1382dc20a302Sas200622 	if (nrow != 1 || ncol != SMB_LGRP_GTBL_NCOL) {
1383dc20a302Sas200622 		sqlite_free_table(result);
1384dc20a302Sas200622 		return (SMB_LGRP_DB_ERROR);
1385dc20a302Sas200622 	}
1386dc20a302Sas200622 
1387dc20a302Sas200622 	rc = smb_lgrp_decode(grp, &result[SMB_LGRP_GTBL_NCOL], infolvl, db);
1388dc20a302Sas200622 	sqlite_free_table(result);
1389dc20a302Sas200622 	return (rc);
1390dc20a302Sas200622 }
1391dc20a302Sas200622 
1392dc20a302Sas200622 /*
1393dc20a302Sas200622  * smb_lgrp_gtbl_exists
1394dc20a302Sas200622  *
1395dc20a302Sas200622  * Checks to see if the given group exists or not.
1396dc20a302Sas200622  */
1397dc20a302Sas200622 static boolean_t
1398dc20a302Sas200622 smb_lgrp_gtbl_exists(sqlite *db, char *gname)
1399dc20a302Sas200622 {
1400dc20a302Sas200622 	char *errmsg = NULL;
1401dc20a302Sas200622 	char *sql;
1402dc20a302Sas200622 	char **result;
1403dc20a302Sas200622 	int nrow, ncol;
1404dc20a302Sas200622 	int rc;
1405dc20a302Sas200622 
1406dc20a302Sas200622 	if (db == NULL)
1407dc20a302Sas200622 		return (NULL);
1408dc20a302Sas200622 
1409dc20a302Sas200622 	sql = sqlite_mprintf("SELECT name FROM groups WHERE name = '%s'",
1410dc20a302Sas200622 	    gname);
1411dc20a302Sas200622 	rc = sqlite_get_table(db, sql, &result, &nrow, &ncol, &errmsg);
1412dc20a302Sas200622 	sqlite_freemem(sql);
1413dc20a302Sas200622 
1414dc20a302Sas200622 	if (rc != SQLITE_OK) {
1415dc20a302Sas200622 		syslog(LOG_DEBUG, "failed to lookup %s (%s)",
1416dc20a302Sas200622 		    gname, NULL_MSGCHK(errmsg));
1417dc20a302Sas200622 		sqlite_freemem(errmsg);
1418dc20a302Sas200622 		return (B_FALSE);
1419dc20a302Sas200622 	}
1420dc20a302Sas200622 
1421dc20a302Sas200622 	sqlite_free_table(result);
1422dc20a302Sas200622 	return (nrow != 0);
1423dc20a302Sas200622 }
1424dc20a302Sas200622 
1425dc20a302Sas200622 /*
1426dc20a302Sas200622  * smb_lgrp_gtbl_count
1427dc20a302Sas200622  *
1428dc20a302Sas200622  * Counts the number of groups in the domain specified by
1429dc20a302Sas200622  * 'dom_idx'
1430dc20a302Sas200622  */
1431dc20a302Sas200622 static int
1432dc20a302Sas200622 smb_lgrp_gtbl_count(sqlite *db, int dom_idx, int *count)
1433dc20a302Sas200622 {
1434dc20a302Sas200622 	char *errmsg = NULL;
1435dc20a302Sas200622 	char *sql;
1436dc20a302Sas200622 	char **result;
1437dc20a302Sas200622 	int nrow, ncol;
1438dc20a302Sas200622 	int rc;
1439dc20a302Sas200622 
1440dc20a302Sas200622 	*count = 0;
1441dc20a302Sas200622 	if (db == NULL)
1442dc20a302Sas200622 		return (SMB_LGRP_DBOPEN_FAILED);
1443dc20a302Sas200622 
1444dc20a302Sas200622 	sql = sqlite_mprintf("SELECT sid_idx FROM groups WHERE sid_idx = %d",
1445dc20a302Sas200622 	    dom_idx);
1446dc20a302Sas200622 	rc = sqlite_get_table(db, sql, &result, &nrow, &ncol, &errmsg);
1447dc20a302Sas200622 	sqlite_freemem(sql);
1448dc20a302Sas200622 
1449dc20a302Sas200622 	if (rc != SQLITE_OK) {
1450dc20a302Sas200622 		syslog(LOG_DEBUG, "failed to count (%s)", NULL_MSGCHK(errmsg));
1451dc20a302Sas200622 		sqlite_freemem(errmsg);
1452dc20a302Sas200622 		return (SMB_LGRP_LOOKUP_FAILED);
1453dc20a302Sas200622 	}
1454dc20a302Sas200622 
1455dc20a302Sas200622 	sqlite_free_table(result);
1456faa1795aSjb150015 	if (ncol > 1)
1457dc20a302Sas200622 		return (SMB_LGRP_DB_ERROR);
1458dc20a302Sas200622 
1459dc20a302Sas200622 	*count = nrow;
1460dc20a302Sas200622 	return (SMB_LGRP_SUCCESS);
1461dc20a302Sas200622 }
1462dc20a302Sas200622 
1463dc20a302Sas200622 /*
1464dc20a302Sas200622  * smb_lgrp_gtbl_insert
1465dc20a302Sas200622  *
1466dc20a302Sas200622  * Insert a record for the given group in the group database.
1467dc20a302Sas200622  *
1468dc20a302Sas200622  * NOTE: this function assumes that this group has no members
1469dc20a302Sas200622  * at this time.
1470dc20a302Sas200622  */
1471dc20a302Sas200622 static int
1472dc20a302Sas200622 smb_lgrp_gtbl_insert(sqlite *db, smb_group_t *grp)
1473dc20a302Sas200622 {
1474dc20a302Sas200622 	smb_lgpid_t privs[SE_MAX_LUID + 1];
1475dc20a302Sas200622 	smb_lgplist_t plist;
1476dc20a302Sas200622 	char *errmsg = NULL;
1477dc20a302Sas200622 	char *sql;
1478dc20a302Sas200622 	int dom_idx;
1479dc20a302Sas200622 	int rc;
1480dc20a302Sas200622 
1481dc20a302Sas200622 	if (db == NULL)
1482dc20a302Sas200622 		return (SMB_LGRP_DBOPEN_FAILED);
1483dc20a302Sas200622 
14849fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	dom_idx = (grp->sg_domain == SMB_DOMAIN_LOCAL)
1485dc20a302Sas200622 	    ? SMB_LGRP_LOCAL_IDX : SMB_LGRP_BUILTIN_IDX;
1486dc20a302Sas200622 
1487dc20a302Sas200622 	plist.p_cnt = SE_MAX_LUID;
1488dc20a302Sas200622 	plist.p_ids = privs;
1489dc20a302Sas200622 	smb_lgrp_encode_privset(grp, &plist);
1490dc20a302Sas200622 
1491dc20a302Sas200622 	sql = sqlite_mprintf("INSERT INTO groups "
1492dc20a302Sas200622 	    "(name, sid_idx, sid_rid, sid_type, sid_attrs, comment, "
1493dc20a302Sas200622 	    "n_privs, privs, n_members, members) "
1494dc20a302Sas200622 	    "VALUES('%s', %u, %u, %u, %u, '%q', %u, '%q', %u, '%q')",
1495dc20a302Sas200622 	    grp->sg_name, dom_idx, grp->sg_rid, grp->sg_id.gs_type,
1496dc20a302Sas200622 	    grp->sg_attr, (grp->sg_cmnt) ? grp->sg_cmnt : "",
1497dc20a302Sas200622 	    plist.p_cnt, (char *)plist.p_ids, 0, "");
1498dc20a302Sas200622 
1499dc20a302Sas200622 	if (sql == NULL)
1500dc20a302Sas200622 		return (SMB_LGRP_NO_MEMORY);
1501dc20a302Sas200622 
1502dc20a302Sas200622 	rc = sqlite_exec(db, sql, NULL, NULL, &errmsg);
1503dc20a302Sas200622 	sqlite_freemem(sql);
1504dc20a302Sas200622 
1505dc20a302Sas200622 	if (rc != SQLITE_OK) {
1506dc20a302Sas200622 		syslog(LOG_DEBUG, "failed to insert %s (%s)",
1507dc20a302Sas200622 		    grp->sg_name, NULL_MSGCHK(errmsg));
1508dc20a302Sas200622 		sqlite_freemem(errmsg);
1509dc20a302Sas200622 		rc = SMB_LGRP_INSERT_FAILED;
1510dc20a302Sas200622 	} else {
1511dc20a302Sas200622 		rc = SMB_LGRP_SUCCESS;
1512dc20a302Sas200622 	}
1513dc20a302Sas200622 
1514dc20a302Sas200622 	return (rc);
1515dc20a302Sas200622 }
1516dc20a302Sas200622 
1517dc20a302Sas200622 /*
1518dc20a302Sas200622  * smb_lgrp_gtbl_delete
1519dc20a302Sas200622  *
1520dc20a302Sas200622  * Removes the specified group from the database
1521dc20a302Sas200622  */
1522dc20a302Sas200622 static int
1523dc20a302Sas200622 smb_lgrp_gtbl_delete(sqlite *db, char *gname)
1524dc20a302Sas200622 {
1525dc20a302Sas200622 	char *errmsg = NULL;
1526dc20a302Sas200622 	char *sql;
1527dc20a302Sas200622 	int rc;
1528dc20a302Sas200622 
1529dc20a302Sas200622 	if (db == NULL)
1530dc20a302Sas200622 		return (SMB_LGRP_DBOPEN_FAILED);
1531dc20a302Sas200622 
1532dc20a302Sas200622 	sql = sqlite_mprintf("DELETE FROM groups WHERE name = '%s'", gname);
1533dc20a302Sas200622 	if (sql == NULL)
1534dc20a302Sas200622 		return (SMB_LGRP_NO_MEMORY);
1535dc20a302Sas200622 
1536dc20a302Sas200622 	rc = sqlite_exec(db, sql, NULL, NULL, &errmsg);
1537dc20a302Sas200622 	sqlite_freemem(sql);
1538dc20a302Sas200622 
1539dc20a302Sas200622 	if (rc != SQLITE_OK) {
1540dc20a302Sas200622 		syslog(LOG_DEBUG, "failed to delete %s (%s)",
1541dc20a302Sas200622 		    gname, NULL_MSGCHK(errmsg));
1542dc20a302Sas200622 		sqlite_freemem(errmsg);
1543dc20a302Sas200622 		rc = SMB_LGRP_DELETE_FAILED;
1544dc20a302Sas200622 	} else {
1545dc20a302Sas200622 		rc = SMB_LGRP_SUCCESS;
1546dc20a302Sas200622 	}
1547dc20a302Sas200622 
1548dc20a302Sas200622 	return (rc);
1549dc20a302Sas200622 }
1550dc20a302Sas200622 
1551dc20a302Sas200622 /*
1552dc20a302Sas200622  * smb_lgrp_gtbl_update
1553dc20a302Sas200622  *
1554dc20a302Sas200622  * Updates the specified group information, the supported items
1555dc20a302Sas200622  * are group name and comment
1556dc20a302Sas200622  */
1557dc20a302Sas200622 static int
1558dc20a302Sas200622 smb_lgrp_gtbl_update(sqlite *db, char *gname, smb_group_t *grp, int col_id)
1559dc20a302Sas200622 {
1560dc20a302Sas200622 	char *errmsg = NULL;
1561dc20a302Sas200622 	char *sql;
1562dc20a302Sas200622 	int rc;
1563dc20a302Sas200622 
1564dc20a302Sas200622 	if (db == NULL)
1565dc20a302Sas200622 		return (SMB_LGRP_DBOPEN_FAILED);
1566dc20a302Sas200622 
1567dc20a302Sas200622 	/* UPDATE doesn't fail if gname doesn't exist */
1568dc20a302Sas200622 	if (!smb_lgrp_gtbl_exists(db, gname))
1569dc20a302Sas200622 		return (SMB_LGRP_NOT_FOUND);
1570dc20a302Sas200622 
1571dc20a302Sas200622 	switch (col_id) {
1572dc20a302Sas200622 	case SMB_LGRP_GTBL_NAME:
1573dc20a302Sas200622 		if (smb_lgrp_gtbl_exists(db, grp->sg_name))
1574dc20a302Sas200622 			return (SMB_LGRP_EXISTS);
1575dc20a302Sas200622 		sql = sqlite_mprintf("UPDATE groups SET name = '%s' "
1576dc20a302Sas200622 		    "WHERE name = '%s'", grp->sg_name, gname);
1577dc20a302Sas200622 		break;
1578dc20a302Sas200622 
1579dc20a302Sas200622 	case SMB_LGRP_GTBL_CMNT:
1580dc20a302Sas200622 		sql = sqlite_mprintf("UPDATE groups SET comment = '%q' "
1581dc20a302Sas200622 		"WHERE name = '%s'", grp->sg_cmnt, gname);
1582dc20a302Sas200622 		break;
1583dc20a302Sas200622 
1584dc20a302Sas200622 	default:
1585dc20a302Sas200622 		return (SMB_LGRP_INVALID_ARG);
1586dc20a302Sas200622 	}
1587dc20a302Sas200622 
1588dc20a302Sas200622 	if (sql == NULL)
1589dc20a302Sas200622 		return (SMB_LGRP_NO_MEMORY);
1590dc20a302Sas200622 
1591dc20a302Sas200622 	rc = sqlite_exec(db, sql, NULL, NULL, &errmsg);
1592dc20a302Sas200622 	sqlite_freemem(sql);
1593dc20a302Sas200622 
1594dc20a302Sas200622 	if (rc != SQLITE_OK) {
1595dc20a302Sas200622 		syslog(LOG_DEBUG, "failed to update %s (%s)",
1596dc20a302Sas200622 		    gname, NULL_MSGCHK(errmsg));
1597dc20a302Sas200622 		sqlite_freemem(errmsg);
1598dc20a302Sas200622 		rc = SMB_LGRP_UPDATE_FAILED;
1599dc20a302Sas200622 	} else {
1600dc20a302Sas200622 		rc = SMB_LGRP_SUCCESS;
1601dc20a302Sas200622 	}
1602dc20a302Sas200622 
1603dc20a302Sas200622 	return (rc);
1604dc20a302Sas200622 }
1605dc20a302Sas200622 
1606dc20a302Sas200622 /*
1607dc20a302Sas200622  * smb_lgrp_gtbl_update_mlist
1608dc20a302Sas200622  *
1609dc20a302Sas200622  * Adds/removes the specified member from the member list of the
1610dc20a302Sas200622  * given group
1611dc20a302Sas200622  */
1612dc20a302Sas200622 static int
1613dc20a302Sas200622 smb_lgrp_gtbl_update_mlist(sqlite *db, char *gname, smb_gsid_t *member,
1614dc20a302Sas200622     int flags)
1615dc20a302Sas200622 {
1616dc20a302Sas200622 	smb_lgmlist_t new_members;
1617dc20a302Sas200622 	smb_lgmlist_t members;
1618dc20a302Sas200622 	smb_lgmid_t mid;
1619dc20a302Sas200622 	char *errmsg = NULL;
1620dc20a302Sas200622 	char *sql;
1621dc20a302Sas200622 	char **result;
1622dc20a302Sas200622 	int nrow, ncol;
1623dc20a302Sas200622 	int rc;
1624dc20a302Sas200622 
1625dc20a302Sas200622 	if (db == NULL)
1626dc20a302Sas200622 		return (SMB_LGRP_DBOPEN_FAILED);
1627dc20a302Sas200622 
1628dc20a302Sas200622 	sql = sqlite_mprintf("SELECT n_members, members FROM groups "
1629dc20a302Sas200622 	    "WHERE name = '%s'", gname);
1630dc20a302Sas200622 
1631dc20a302Sas200622 	if (sql == NULL)
1632dc20a302Sas200622 		return (SMB_LGRP_NO_MEMORY);
1633dc20a302Sas200622 
1634dc20a302Sas200622 	rc = sqlite_get_table(db, sql, &result, &nrow, &ncol, &errmsg);
1635dc20a302Sas200622 	sqlite_freemem(sql);
1636dc20a302Sas200622 
1637dc20a302Sas200622 	if (rc != SQLITE_OK) {
1638dc20a302Sas200622 		syslog(LOG_DEBUG, "failed to lookup %s (%s)",
1639dc20a302Sas200622 		    gname, NULL_MSGCHK(errmsg));
1640dc20a302Sas200622 		sqlite_freemem(errmsg);
1641dc20a302Sas200622 		return (SMB_LGRP_LOOKUP_FAILED);
1642dc20a302Sas200622 	}
1643dc20a302Sas200622 
1644dc20a302Sas200622 	if (nrow == 0)  {
1645dc20a302Sas200622 		/* group not found */
1646dc20a302Sas200622 		sqlite_free_table(result);
1647dc20a302Sas200622 		return (SMB_LGRP_NOT_FOUND);
1648dc20a302Sas200622 	}
1649dc20a302Sas200622 
1650dc20a302Sas200622 	if (nrow != 1 || ncol != 2) {
1651dc20a302Sas200622 		sqlite_free_table(result);
1652dc20a302Sas200622 		return (SMB_LGRP_DB_ERROR);
1653dc20a302Sas200622 	}
1654dc20a302Sas200622 
1655dc20a302Sas200622 	bzero(&mid, sizeof (mid));
1656dc20a302Sas200622 	mid.m_type = member->gs_type;
1657dc20a302Sas200622 	rc = smb_lgrp_dtbl_getidx(db, member->gs_sid, mid.m_type,
1658dc20a302Sas200622 	    &mid.m_idx, &mid.m_rid);
1659dc20a302Sas200622 	if (rc != SMB_LGRP_SUCCESS) {
1660dc20a302Sas200622 		sqlite_free_table(result);
1661dc20a302Sas200622 		return (rc);
1662dc20a302Sas200622 	}
1663dc20a302Sas200622 
1664dc20a302Sas200622 	members.m_cnt = atoi(result[2]);
1665dc20a302Sas200622 	members.m_ids = result[3];
1666dc20a302Sas200622 
1667dc20a302Sas200622 	switch (flags) {
1668dc20a302Sas200622 	case SMB_LGRP_DB_ADDMEMBER:
1669dc20a302Sas200622 		rc = smb_lgrp_mlist_add(&members, &mid, &new_members);
1670dc20a302Sas200622 		break;
1671dc20a302Sas200622 	case SMB_LGRP_DB_DELMEMBER:
1672dc20a302Sas200622 		rc = smb_lgrp_mlist_del(&members, &mid, &new_members);
1673dc20a302Sas200622 		break;
1674dc20a302Sas200622 	default:
1675dc20a302Sas200622 		rc = SMB_LGRP_INVALID_ARG;
1676dc20a302Sas200622 	}
1677dc20a302Sas200622 
1678dc20a302Sas200622 	sqlite_free_table(result);
1679dc20a302Sas200622 	if (rc != SMB_LGRP_SUCCESS)
1680dc20a302Sas200622 		return (rc);
1681dc20a302Sas200622 
1682dc20a302Sas200622 	sql = sqlite_mprintf("UPDATE groups SET n_members = %u, members = '%s'"
1683dc20a302Sas200622 	    " WHERE name = '%s'", new_members.m_cnt, new_members.m_ids, gname);
1684dc20a302Sas200622 
1685dc20a302Sas200622 	free(new_members.m_ids);
1686dc20a302Sas200622 
1687dc20a302Sas200622 	if (sql == NULL)
1688dc20a302Sas200622 		return (SMB_LGRP_NO_MEMORY);
1689dc20a302Sas200622 
1690dc20a302Sas200622 	rc = sqlite_exec(db, sql, NULL, NULL, &errmsg);
1691dc20a302Sas200622 	sqlite_freemem(sql);
1692dc20a302Sas200622 
1693dc20a302Sas200622 	if (rc != SQLITE_OK) {
1694dc20a302Sas200622 		syslog(LOG_DEBUG, "failed to update %s (%s)", gname,
1695dc20a302Sas200622 		    NULL_MSGCHK(errmsg));
1696dc20a302Sas200622 		sqlite_freemem(errmsg);
1697dc20a302Sas200622 		rc = SMB_LGRP_UPDATE_FAILED;
1698dc20a302Sas200622 	} else {
1699dc20a302Sas200622 		rc = SMB_LGRP_SUCCESS;
1700dc20a302Sas200622 	}
1701dc20a302Sas200622 
1702dc20a302Sas200622 	return (rc);
1703dc20a302Sas200622 }
1704dc20a302Sas200622 
1705dc20a302Sas200622 /*
1706dc20a302Sas200622  * smb_lgrp_gtbl_update_plist
1707dc20a302Sas200622  *
1708dc20a302Sas200622  * Adds/removes the specified privilege from the privilege list of the
1709dc20a302Sas200622  * given group
1710dc20a302Sas200622  */
1711dc20a302Sas200622 static int
1712dc20a302Sas200622 smb_lgrp_gtbl_update_plist(sqlite *db, char *gname, uint8_t priv_id,
1713dc20a302Sas200622     boolean_t enable)
1714dc20a302Sas200622 {
1715dc20a302Sas200622 	char *sql;
1716dc20a302Sas200622 	char *errmsg = NULL;
1717dc20a302Sas200622 	char **result;
1718dc20a302Sas200622 	int nrow, ncol;
1719dc20a302Sas200622 	int rc;
1720dc20a302Sas200622 	smb_lgplist_t privs;
1721dc20a302Sas200622 	smb_lgplist_t new_privs;
1722dc20a302Sas200622 
1723dc20a302Sas200622 	if (db == NULL)
1724dc20a302Sas200622 		return (SMB_LGRP_DBOPEN_FAILED);
1725dc20a302Sas200622 
1726dc20a302Sas200622 	sql = sqlite_mprintf("SELECT n_privs, privs FROM groups "
1727dc20a302Sas200622 	    "WHERE name = '%s'", gname);
1728dc20a302Sas200622 
1729dc20a302Sas200622 	if (sql == NULL)
1730dc20a302Sas200622 		return (SMB_LGRP_NO_MEMORY);
1731dc20a302Sas200622 
1732dc20a302Sas200622 	rc = sqlite_get_table(db, sql, &result, &nrow, &ncol, &errmsg);
1733dc20a302Sas200622 	sqlite_freemem(sql);
1734dc20a302Sas200622 
1735dc20a302Sas200622 	if (rc != SQLITE_OK) {
1736dc20a302Sas200622 		syslog(LOG_DEBUG, "failed to lookup %s (%s)",
1737dc20a302Sas200622 		    gname, NULL_MSGCHK(errmsg));
1738dc20a302Sas200622 		sqlite_freemem(errmsg);
1739dc20a302Sas200622 		return (SMB_LGRP_LOOKUP_FAILED);
1740dc20a302Sas200622 	}
1741dc20a302Sas200622 
1742dc20a302Sas200622 	if (nrow == 0)  {
1743dc20a302Sas200622 		/* group not found */
1744dc20a302Sas200622 		sqlite_free_table(result);
1745dc20a302Sas200622 		return (SMB_LGRP_NOT_FOUND);
1746dc20a302Sas200622 	}
1747dc20a302Sas200622 
1748dc20a302Sas200622 	if (nrow != 1 || ncol != 2) {
1749dc20a302Sas200622 		sqlite_free_table(result);
1750dc20a302Sas200622 		return (SMB_LGRP_DB_ERROR);
1751dc20a302Sas200622 	}
1752dc20a302Sas200622 
1753dc20a302Sas200622 	privs.p_cnt = atoi(result[2]);
1754dc20a302Sas200622 	privs.p_ids = (smb_lgpid_t *)result[3];
1755dc20a302Sas200622 
1756dc20a302Sas200622 	if (enable)
1757dc20a302Sas200622 		rc = smb_lgrp_plist_add(&privs, priv_id, &new_privs);
1758dc20a302Sas200622 	else
1759dc20a302Sas200622 		rc = smb_lgrp_plist_del(&privs, priv_id, &new_privs);
1760dc20a302Sas200622 
1761dc20a302Sas200622 	sqlite_free_table(result);
1762dc20a302Sas200622 	if (rc != SMB_LGRP_SUCCESS)
1763dc20a302Sas200622 		return (rc);
1764dc20a302Sas200622 
1765dc20a302Sas200622 	sql = sqlite_mprintf("UPDATE groups SET n_privs = %u, privs = '%q'"
1766dc20a302Sas200622 	    " WHERE name = '%s'", new_privs.p_cnt, (char *)new_privs.p_ids,
1767dc20a302Sas200622 	    gname);
1768dc20a302Sas200622 
1769dc20a302Sas200622 	free(new_privs.p_ids);
1770dc20a302Sas200622 
1771dc20a302Sas200622 	if (sql == NULL)
1772dc20a302Sas200622 		return (SMB_LGRP_NO_MEMORY);
1773dc20a302Sas200622 
1774dc20a302Sas200622 	rc = sqlite_exec(db, sql, NULL, NULL, &errmsg);
1775dc20a302Sas200622 	sqlite_freemem(sql);
1776dc20a302Sas200622 
1777dc20a302Sas200622 	if (rc != SQLITE_OK) {
1778dc20a302Sas200622 		syslog(LOG_DEBUG, "failed to update %s (%s)",
1779dc20a302Sas200622 		    gname, NULL_MSGCHK(errmsg));
1780dc20a302Sas200622 		sqlite_freemem(errmsg);
1781dc20a302Sas200622 		rc = SMB_LGRP_UPDATE_FAILED;
1782dc20a302Sas200622 	} else {
1783dc20a302Sas200622 		rc = SMB_LGRP_SUCCESS;
1784dc20a302Sas200622 	}
1785dc20a302Sas200622 
1786dc20a302Sas200622 	return (rc);
1787dc20a302Sas200622 }
1788dc20a302Sas200622 
1789dc20a302Sas200622 /*
1790dc20a302Sas200622  * smb_lgrp_dtbl_insert
1791dc20a302Sas200622  *
1792dc20a302Sas200622  * Inserts the specified domain SID in the dmain table.
1793dc20a302Sas200622  * Upon successful insert the index will be returned in
1794dc20a302Sas200622  * 'dom_idx' arg.
1795dc20a302Sas200622  */
1796dc20a302Sas200622 static int
1797dc20a302Sas200622 smb_lgrp_dtbl_insert(sqlite *db, char *dom_sid, uint32_t *dom_idx)
1798dc20a302Sas200622 {
1799dc20a302Sas200622 	char *errmsg = NULL;
1800dc20a302Sas200622 	char *sql;
1801dc20a302Sas200622 	int rc;
1802dc20a302Sas200622 
1803dc20a302Sas200622 	sql = sqlite_mprintf("INSERT INTO domains (dom_sid, dom_cnt)"
1804dc20a302Sas200622 	    " VALUES('%s', 1);", dom_sid);
1805dc20a302Sas200622 	if (sql == NULL)
1806dc20a302Sas200622 		return (SMB_LGRP_NO_MEMORY);
1807dc20a302Sas200622 
1808dc20a302Sas200622 	rc = sqlite_exec(db, sql, NULL, NULL, &errmsg);
1809dc20a302Sas200622 	sqlite_freemem(sql);
1810dc20a302Sas200622 
1811dc20a302Sas200622 	if (rc != SQLITE_OK) {
1812dc20a302Sas200622 		syslog(LOG_DEBUG, "failed to insert domain SID (%s)",
1813dc20a302Sas200622 		    NULL_MSGCHK(errmsg));
1814dc20a302Sas200622 		sqlite_freemem(errmsg);
1815dc20a302Sas200622 		return (SMB_LGRP_DOMINS_FAILED);
1816dc20a302Sas200622 	}
1817dc20a302Sas200622 
1818dc20a302Sas200622 	if (dom_idx)
1819dc20a302Sas200622 		*dom_idx = sqlite_last_insert_rowid(db);
1820dc20a302Sas200622 	return (SMB_LGRP_SUCCESS);
1821dc20a302Sas200622 }
1822dc20a302Sas200622 
1823dc20a302Sas200622 /*
1824dc20a302Sas200622  * smb_lgrp_dtbl_getidx
1825dc20a302Sas200622  *
1826dc20a302Sas200622  * Searches the domain table for the domain SID of the
1827dc20a302Sas200622  * given member SID. If it finds the domain SID it'll
1828dc20a302Sas200622  * return the index and the RID, otherwise it'll insert
1829dc20a302Sas200622  * it in the domain table as a new SID.
1830dc20a302Sas200622  */
1831dc20a302Sas200622 static int
18326537f381Sas200622 smb_lgrp_dtbl_getidx(sqlite *db, smb_sid_t *sid, uint16_t sid_type,
1833dc20a302Sas200622     uint32_t *dom_idx, uint32_t *rid)
1834dc20a302Sas200622 {
18356537f381Sas200622 	char sidstr[SMB_SID_STRSZ];
18366537f381Sas200622 	smb_sid_t *dom_sid;
1837dc20a302Sas200622 	char **result;
1838dc20a302Sas200622 	int nrow, ncol;
1839dc20a302Sas200622 	char *errmsg = NULL;
1840dc20a302Sas200622 	char *sql;
1841dc20a302Sas200622 	int rc;
1842dc20a302Sas200622 
18439fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (smb_sid_indomain(smb_localgrp.lg_machine_sid, sid)) {
1844dc20a302Sas200622 		/* This is a local SID */
1845dc20a302Sas200622 		int id_type = (sid_type == SidTypeUser)
1846dc20a302Sas200622 		    ? SMB_IDMAP_USER : SMB_IDMAP_GROUP;
1847dc20a302Sas200622 		*dom_idx = SMB_LGRP_LOCAL_IDX;
1848dc20a302Sas200622 		if (smb_idmap_getid(sid, rid, &id_type) != IDMAP_SUCCESS)
1849dc20a302Sas200622 			return (SMB_LGRP_INTERNAL_ERROR);
1850faa1795aSjb150015 
1851faa1795aSjb150015 		return (SMB_LGRP_SUCCESS);
1852dc20a302Sas200622 	}
1853dc20a302Sas200622 
18547f667e74Sjose borrego 	if ((dom_sid = smb_sid_split(sid, rid)) == NULL)
1855dc20a302Sas200622 		return (SMB_LGRP_NO_MEMORY);
1856dc20a302Sas200622 
18576537f381Sas200622 	smb_sid_tostr(dom_sid, sidstr);
1858dc20a302Sas200622 	free(dom_sid);
1859dc20a302Sas200622 
1860dc20a302Sas200622 	sql = sqlite_mprintf("SELECT dom_idx FROM domains WHERE dom_sid = '%s'",
1861dc20a302Sas200622 	    sidstr);
1862dc20a302Sas200622 	if (sql == NULL)
1863dc20a302Sas200622 		return (SMB_LGRP_NO_MEMORY);
1864dc20a302Sas200622 
1865dc20a302Sas200622 	rc = sqlite_get_table(db, sql, &result, &nrow, &ncol, &errmsg);
1866dc20a302Sas200622 	sqlite_freemem(sql);
1867dc20a302Sas200622 
1868dc20a302Sas200622 	if (rc != SQLITE_OK) {
1869dc20a302Sas200622 		syslog(LOG_DEBUG, "failed to lookup domain SID (%s)",
1870dc20a302Sas200622 		    NULL_MSGCHK(errmsg));
1871dc20a302Sas200622 		sqlite_freemem(errmsg);
1872dc20a302Sas200622 		return (SMB_LGRP_DOMLKP_FAILED);
1873dc20a302Sas200622 	}
1874dc20a302Sas200622 
1875dc20a302Sas200622 	switch (nrow) {
1876dc20a302Sas200622 	case 0:
1877dc20a302Sas200622 		/* new domain SID; insert it into the domains table */
1878dc20a302Sas200622 		sqlite_free_table(result);
1879dc20a302Sas200622 		return (smb_lgrp_dtbl_insert(db, sidstr, dom_idx));
1880dc20a302Sas200622 
1881dc20a302Sas200622 	case 1:
1882dc20a302Sas200622 		*dom_idx = atoi(result[1]);
1883dc20a302Sas200622 		sqlite_free_table(result);
1884dc20a302Sas200622 		return (SMB_LGRP_SUCCESS);
1885dc20a302Sas200622 	}
1886dc20a302Sas200622 
1887dc20a302Sas200622 	sqlite_free_table(result);
1888dc20a302Sas200622 	return (SMB_LGRP_DB_ERROR);
1889dc20a302Sas200622 }
1890dc20a302Sas200622 
1891dc20a302Sas200622 /*
1892dc20a302Sas200622  * smb_lgrp_dtbl_getsid
1893dc20a302Sas200622  *
1894dc20a302Sas200622  * Searchs the domain table for the given domain index.
1895dc20a302Sas200622  * Converts the found domain SID to binary format and
1896dc20a302Sas200622  * returns it in the 'sid' arg.
1897dc20a302Sas200622  *
1898dc20a302Sas200622  * Caller must free the returned SID by calling free().
1899dc20a302Sas200622  */
1900dc20a302Sas200622 static int
19016537f381Sas200622 smb_lgrp_dtbl_getsid(sqlite *db, uint32_t dom_idx, smb_sid_t **sid)
1902dc20a302Sas200622 {
1903dc20a302Sas200622 	char **result;
1904dc20a302Sas200622 	int nrow, ncol;
1905dc20a302Sas200622 	char *errmsg = NULL;
1906dc20a302Sas200622 	char *sql;
1907dc20a302Sas200622 	int rc;
1908dc20a302Sas200622 
1909dc20a302Sas200622 	sql = sqlite_mprintf("SELECT dom_sid FROM domains WHERE dom_idx = %u",
1910dc20a302Sas200622 	    dom_idx);
1911dc20a302Sas200622 	if (sql == NULL)
1912dc20a302Sas200622 		return (SMB_LGRP_NO_MEMORY);
1913dc20a302Sas200622 
1914dc20a302Sas200622 	rc = sqlite_get_table(db, sql, &result, &nrow, &ncol, &errmsg);
1915dc20a302Sas200622 	sqlite_freemem(sql);
1916dc20a302Sas200622 
1917dc20a302Sas200622 	if (rc != SQLITE_OK) {
1918dc20a302Sas200622 		syslog(LOG_DEBUG, "failed to lookup domain index (%s)",
1919dc20a302Sas200622 		    NULL_MSGCHK(errmsg));
1920dc20a302Sas200622 		sqlite_freemem(errmsg);
1921dc20a302Sas200622 		return (SMB_LGRP_DOMLKP_FAILED);
1922dc20a302Sas200622 	}
1923dc20a302Sas200622 
1924dc20a302Sas200622 	switch (nrow) {
1925dc20a302Sas200622 	case 0:
1926dc20a302Sas200622 		rc = SMB_LGRP_NO_SUCH_DOMAIN;
1927dc20a302Sas200622 		break;
1928dc20a302Sas200622 
1929dc20a302Sas200622 	case 1:
19306537f381Sas200622 		*sid = smb_sid_fromstr(result[1]);
1931dc20a302Sas200622 		rc = (*sid == NULL)
1932dc20a302Sas200622 		    ? SMB_LGRP_INTERNAL_ERROR : SMB_LGRP_SUCCESS;
1933dc20a302Sas200622 		break;
1934dc20a302Sas200622 
1935dc20a302Sas200622 	default:
1936dc20a302Sas200622 		rc = SMB_LGRP_DB_ERROR;
1937dc20a302Sas200622 		break;
1938dc20a302Sas200622 	}
1939dc20a302Sas200622 
1940dc20a302Sas200622 	sqlite_free_table(result);
1941dc20a302Sas200622 	return (rc);
1942dc20a302Sas200622 }
1943dc20a302Sas200622 
1944dc20a302Sas200622 /*
1945dc20a302Sas200622  * smb_lgrp_db_setinfo
1946dc20a302Sas200622  *
1947dc20a302Sas200622  * Initializes the db_info table upon database creation.
1948dc20a302Sas200622  */
1949dc20a302Sas200622 static int
1950dc20a302Sas200622 smb_lgrp_db_setinfo(sqlite *db)
1951dc20a302Sas200622 {
1952dc20a302Sas200622 	char *errmsg = NULL;
1953dc20a302Sas200622 	char *sql;
1954dc20a302Sas200622 	int rc;
1955dc20a302Sas200622 
1956dc20a302Sas200622 	sql = sqlite_mprintf("INSERT INTO db_info (ver_major, ver_minor,"
1957dc20a302Sas200622 	    " magic) VALUES (%d, %d, %u)", SMB_LGRP_DB_VERMAJOR,
1958dc20a302Sas200622 	    SMB_LGRP_DB_VERMINOR, SMB_LGRP_DB_MAGIC);
1959dc20a302Sas200622 
1960dc20a302Sas200622 	if (sql == NULL)
1961dc20a302Sas200622 		return (SMB_LGRP_NO_MEMORY);
1962dc20a302Sas200622 
1963dc20a302Sas200622 	rc = sqlite_exec(db, sql, NULL, NULL, &errmsg);
1964dc20a302Sas200622 	sqlite_freemem(sql);
1965dc20a302Sas200622 	if (rc != SQLITE_OK) {
1966dc20a302Sas200622 		syslog(LOG_DEBUG, "failed to insert database information (%s)",
1967dc20a302Sas200622 		    NULL_MSGCHK(errmsg));
1968dc20a302Sas200622 		sqlite_freemem(errmsg);
1969dc20a302Sas200622 		rc = SMB_LGRP_DBINIT_ERROR;
1970dc20a302Sas200622 	} else {
1971dc20a302Sas200622 		rc = SMB_LGRP_SUCCESS;
1972dc20a302Sas200622 	}
1973dc20a302Sas200622 
1974dc20a302Sas200622 	return (rc);
1975dc20a302Sas200622 }
1976dc20a302Sas200622 
1977dc20a302Sas200622 /*
1978dc20a302Sas200622  * smb_lgrp_mlist_add
1979dc20a302Sas200622  *
1980dc20a302Sas200622  * Adds the given member (newm) to the input member list (in_members)
1981dc20a302Sas200622  * if it's not already there. The result list will be returned in
1982dc20a302Sas200622  * out_members. The caller must free the allocated memory for
1983dc20a302Sas200622  * out_members by calling free().
1984dc20a302Sas200622  *
1985dc20a302Sas200622  * in_members and out_members are hex strings.
1986dc20a302Sas200622  */
1987dc20a302Sas200622 static int
1988dc20a302Sas200622 smb_lgrp_mlist_add(smb_lgmlist_t *in_members, smb_lgmid_t *newm,
1989dc20a302Sas200622     smb_lgmlist_t *out_members)
1990dc20a302Sas200622 {
1991dc20a302Sas200622 	char mid_hex[SMB_LGRP_MID_HEXSZ];
1992dc20a302Sas200622 	char *in_list;
1993dc20a302Sas200622 	char *out_list;
1994dc20a302Sas200622 	int in_size;
1995dc20a302Sas200622 	int out_size;
1996dc20a302Sas200622 	int mid_hexsz;
1997dc20a302Sas200622 	int i;
1998dc20a302Sas200622 
1999dc20a302Sas200622 	out_members->m_cnt = 0;
2000dc20a302Sas200622 	out_members->m_ids = NULL;
2001dc20a302Sas200622 
2002dc20a302Sas200622 	bzero(mid_hex, sizeof (mid_hex));
2003dc20a302Sas200622 	mid_hexsz = bintohex((const char *)newm, sizeof (smb_lgmid_t),
2004dc20a302Sas200622 	    mid_hex, sizeof (mid_hex));
2005dc20a302Sas200622 
2006dc20a302Sas200622 	/*
2007dc20a302Sas200622 	 * Check to see if this is already a group member
2008dc20a302Sas200622 	 */
2009dc20a302Sas200622 	in_list = in_members->m_ids;
2010dc20a302Sas200622 	for (i = 0; i < in_members->m_cnt; i++) {
2011dc20a302Sas200622 		if (strncmp(in_list, mid_hex, mid_hexsz) == 0)
2012dc20a302Sas200622 			return (SMB_LGRP_MEMBER_IN_GROUP);
2013dc20a302Sas200622 		in_list += mid_hexsz;
2014dc20a302Sas200622 	}
2015dc20a302Sas200622 
2016dc20a302Sas200622 	in_size = (in_members->m_ids) ? strlen(in_members->m_ids) : 0;
2017dc20a302Sas200622 	out_size = in_size + sizeof (mid_hex) + 1;
2018dc20a302Sas200622 	out_list = malloc(out_size);
2019dc20a302Sas200622 	if (out_list == NULL)
2020dc20a302Sas200622 		return (SMB_LGRP_NO_MEMORY);
2021dc20a302Sas200622 
2022dc20a302Sas200622 	bzero(out_list, out_size);
2023dc20a302Sas200622 	if (in_members->m_ids)
2024dc20a302Sas200622 		(void) strlcpy(out_list, in_members->m_ids, out_size);
2025dc20a302Sas200622 	(void) strcat(out_list, mid_hex);
2026dc20a302Sas200622 
2027dc20a302Sas200622 	out_members->m_cnt = in_members->m_cnt + 1;
2028dc20a302Sas200622 	out_members->m_ids = out_list;
2029dc20a302Sas200622 
2030dc20a302Sas200622 	return (SMB_LGRP_SUCCESS);
2031dc20a302Sas200622 }
2032dc20a302Sas200622 
2033dc20a302Sas200622 /*
2034dc20a302Sas200622  * smb_lgrp_mlist_del
2035dc20a302Sas200622  *
2036dc20a302Sas200622  * Removes the given member (msid) from the input member list
2037dc20a302Sas200622  * (in_members) if it's already there. The result list will b
2038dc20a302Sas200622  * returned in out_members. The caller must free the allocated
2039dc20a302Sas200622  * memory for out_members by calling free().
2040dc20a302Sas200622  *
2041dc20a302Sas200622  * in_members and out_members are hex strings.
2042dc20a302Sas200622  */
2043dc20a302Sas200622 static int
2044dc20a302Sas200622 smb_lgrp_mlist_del(smb_lgmlist_t *in_members, smb_lgmid_t *mid,
2045dc20a302Sas200622     smb_lgmlist_t *out_members)
2046dc20a302Sas200622 {
2047dc20a302Sas200622 	char mid_hex[SMB_LGRP_MID_HEXSZ];
2048dc20a302Sas200622 	char *in_list;
2049dc20a302Sas200622 	char *out_list;
2050dc20a302Sas200622 	int in_size;
2051dc20a302Sas200622 	int out_size;
2052dc20a302Sas200622 	int mid_hexsz;
2053dc20a302Sas200622 	int out_cnt;
2054dc20a302Sas200622 	int i;
2055dc20a302Sas200622 
2056dc20a302Sas200622 	out_members->m_cnt = 0;
2057dc20a302Sas200622 	out_members->m_ids = NULL;
2058dc20a302Sas200622 
2059dc20a302Sas200622 	if ((in_members == NULL) || (in_members->m_cnt == 0))
2060dc20a302Sas200622 		return (SMB_LGRP_MEMBER_NOT_IN_GROUP);
2061dc20a302Sas200622 
2062dc20a302Sas200622 	in_size = strlen(in_members->m_ids);
2063dc20a302Sas200622 	out_size = in_size + sizeof (mid_hex) + 1;
2064dc20a302Sas200622 	out_list = malloc(out_size);
2065dc20a302Sas200622 	if (out_list == NULL)
2066dc20a302Sas200622 		return (SMB_LGRP_NO_MEMORY);
2067dc20a302Sas200622 
2068dc20a302Sas200622 	*out_list = '\0';
2069dc20a302Sas200622 
2070dc20a302Sas200622 	bzero(mid_hex, sizeof (mid_hex));
2071dc20a302Sas200622 	mid_hexsz = bintohex((const char *)mid, sizeof (smb_lgmid_t),
2072dc20a302Sas200622 	    mid_hex, sizeof (mid_hex));
2073dc20a302Sas200622 
2074dc20a302Sas200622 	in_list = in_members->m_ids;
2075dc20a302Sas200622 	for (i = 0, out_cnt = 0; i < in_members->m_cnt; i++) {
2076dc20a302Sas200622 		if (strncmp(in_list, mid_hex, mid_hexsz)) {
2077dc20a302Sas200622 			(void) strncat(out_list, in_list, mid_hexsz);
2078dc20a302Sas200622 			out_cnt++;
2079dc20a302Sas200622 		}
2080dc20a302Sas200622 		in_list += mid_hexsz;
2081dc20a302Sas200622 	}
2082dc20a302Sas200622 
2083dc20a302Sas200622 	if (out_cnt == in_members->m_cnt) {
2084dc20a302Sas200622 		free(out_list);
2085dc20a302Sas200622 		return (SMB_LGRP_MEMBER_NOT_IN_GROUP);
2086dc20a302Sas200622 	}
2087dc20a302Sas200622 
2088dc20a302Sas200622 	out_members->m_cnt = out_cnt;
2089dc20a302Sas200622 	out_members->m_ids = out_list;
2090dc20a302Sas200622 	return (SMB_LGRP_SUCCESS);
2091dc20a302Sas200622 }
2092dc20a302Sas200622 
2093dc20a302Sas200622 /*
2094dc20a302Sas200622  * smb_lgrp_plist_add
2095dc20a302Sas200622  *
2096dc20a302Sas200622  * Adds the given privilege to the input list (in_privs)
2097dc20a302Sas200622  * if it's not already there. The result list is returned
2098dc20a302Sas200622  * in out_privs. The caller must free the allocated memory
2099dc20a302Sas200622  * for out_privs by calling free().
2100dc20a302Sas200622  */
2101dc20a302Sas200622 static int
2102dc20a302Sas200622 smb_lgrp_plist_add(smb_lgplist_t *in_privs, smb_lgpid_t priv_id,
2103dc20a302Sas200622     smb_lgplist_t *out_privs)
2104dc20a302Sas200622 {
2105dc20a302Sas200622 	int i, size;
2106dc20a302Sas200622 	smb_lgpid_t *pbuf;
2107dc20a302Sas200622 
2108dc20a302Sas200622 	out_privs->p_cnt = 0;
2109dc20a302Sas200622 	out_privs->p_ids = NULL;
2110dc20a302Sas200622 
2111dc20a302Sas200622 	for (i = 0; i < in_privs->p_cnt; i++) {
2112dc20a302Sas200622 		if (in_privs->p_ids[i] == priv_id)
2113dc20a302Sas200622 			return (SMB_LGRP_PRIV_HELD);
2114dc20a302Sas200622 	}
2115dc20a302Sas200622 
2116dc20a302Sas200622 	size = (in_privs->p_cnt + 1) * sizeof (smb_lgpid_t) + 1;
2117dc20a302Sas200622 	pbuf = malloc(size);
2118dc20a302Sas200622 	if (pbuf == NULL)
2119dc20a302Sas200622 		return (SMB_LGRP_NO_MEMORY);
2120dc20a302Sas200622 
2121dc20a302Sas200622 	bzero(pbuf, size);
2122dc20a302Sas200622 	bcopy(in_privs->p_ids, pbuf, in_privs->p_cnt * sizeof (smb_lgpid_t));
2123dc20a302Sas200622 	pbuf[in_privs->p_cnt] = priv_id;
2124dc20a302Sas200622 
2125dc20a302Sas200622 	out_privs->p_cnt = in_privs->p_cnt + 1;
2126dc20a302Sas200622 	out_privs->p_ids = pbuf;
2127dc20a302Sas200622 
2128dc20a302Sas200622 	return (SMB_LGRP_SUCCESS);
2129dc20a302Sas200622 }
2130dc20a302Sas200622 
2131dc20a302Sas200622 /*
2132dc20a302Sas200622  * smb_lgrp_plist_del
2133dc20a302Sas200622  *
2134dc20a302Sas200622  * Removes the given privilege from the input list (in_privs)
2135dc20a302Sas200622  * if it's already there. The result list is returned
2136dc20a302Sas200622  * in out_privs. The caller must free the allocated memory
2137dc20a302Sas200622  * for out_privs by calling free().
2138dc20a302Sas200622  */
2139dc20a302Sas200622 static int
2140dc20a302Sas200622 smb_lgrp_plist_del(smb_lgplist_t *in_privs, smb_lgpid_t priv_id,
2141dc20a302Sas200622     smb_lgplist_t *out_privs)
2142dc20a302Sas200622 {
2143dc20a302Sas200622 	int i, size;
2144dc20a302Sas200622 
2145dc20a302Sas200622 	out_privs->p_cnt = 0;
2146dc20a302Sas200622 	out_privs->p_ids = NULL;
2147dc20a302Sas200622 
2148dc20a302Sas200622 	if ((in_privs == NULL) || (in_privs->p_cnt == 0))
2149dc20a302Sas200622 		return (SMB_LGRP_PRIV_NOT_HELD);
2150dc20a302Sas200622 
2151dc20a302Sas200622 	size = (in_privs->p_cnt - 1) * sizeof (smb_lgpid_t) + 1;
2152dc20a302Sas200622 	out_privs->p_ids = malloc(size);
2153dc20a302Sas200622 	if (out_privs->p_ids == NULL)
2154dc20a302Sas200622 		return (SMB_LGRP_NO_MEMORY);
2155dc20a302Sas200622 
2156dc20a302Sas200622 	bzero(out_privs->p_ids, size);
2157dc20a302Sas200622 
2158dc20a302Sas200622 	for (i = 0; i < in_privs->p_cnt; i++) {
2159dc20a302Sas200622 		if (in_privs->p_ids[i] != priv_id)
2160dc20a302Sas200622 			out_privs->p_ids[out_privs->p_cnt++] =
2161dc20a302Sas200622 			    in_privs->p_ids[i];
2162dc20a302Sas200622 	}
2163dc20a302Sas200622 
2164dc20a302Sas200622 	if (out_privs->p_cnt == in_privs->p_cnt) {
2165dc20a302Sas200622 		free(out_privs->p_ids);
2166dc20a302Sas200622 		out_privs->p_cnt = 0;
2167dc20a302Sas200622 		out_privs->p_ids = NULL;
2168dc20a302Sas200622 		return (SMB_LGRP_PRIV_NOT_HELD);
2169dc20a302Sas200622 	}
2170dc20a302Sas200622 
2171dc20a302Sas200622 	return (SMB_LGRP_SUCCESS);
2172dc20a302Sas200622 }
2173dc20a302Sas200622 
2174dc20a302Sas200622 /*
2175dc20a302Sas200622  * smb_lgrp_encode_privset
2176dc20a302Sas200622  *
2177dc20a302Sas200622  * Encodes given privilege set into a buffer to be stored in the group
2178dc20a302Sas200622  * database. Each entry of the encoded buffer contains the privilege ID
2179dc20a302Sas200622  * of an enable privilege. The returned buffer is null-terminated.
2180dc20a302Sas200622  */
2181dc20a302Sas200622 static void
2182dc20a302Sas200622 smb_lgrp_encode_privset(smb_group_t *grp, smb_lgplist_t *plist)
2183dc20a302Sas200622 {
2184dc20a302Sas200622 	smb_privset_t *privs;
2185dc20a302Sas200622 	uint32_t pcnt = plist->p_cnt;
2186dc20a302Sas200622 	int i;
2187dc20a302Sas200622 
2188dc20a302Sas200622 	bzero(plist->p_ids, sizeof (smb_lgpid_t) * plist->p_cnt);
2189dc20a302Sas200622 	plist->p_cnt = 0;
2190dc20a302Sas200622 
2191dc20a302Sas200622 	privs = grp->sg_privs;
2192dc20a302Sas200622 	if ((privs == NULL) || (privs->priv_cnt == 0))
2193dc20a302Sas200622 		return;
2194dc20a302Sas200622 
2195dc20a302Sas200622 	if (pcnt < privs->priv_cnt) {
2196dc20a302Sas200622 		assert(0);
2197dc20a302Sas200622 	}
2198dc20a302Sas200622 
2199dc20a302Sas200622 	for (i = 0; i < privs->priv_cnt; i++) {
2200dc20a302Sas200622 		if (privs->priv[i].attrs == SE_PRIVILEGE_ENABLED) {
2201dc20a302Sas200622 			plist->p_ids[plist->p_cnt++] =
2202dc20a302Sas200622 			    (uint8_t)privs->priv[i].luid.lo_part;
2203dc20a302Sas200622 		}
2204dc20a302Sas200622 	}
2205dc20a302Sas200622 }
2206dc20a302Sas200622 
2207dc20a302Sas200622 /*
2208dc20a302Sas200622  * smb_lgrp_decode_privset
2209dc20a302Sas200622  *
2210dc20a302Sas200622  * Decodes the privilege information read from group table
2211dc20a302Sas200622  * (nprivs, privs) into a binray format specified by the
2212dc20a302Sas200622  * privilege field of smb_group_t
2213dc20a302Sas200622  */
2214dc20a302Sas200622 static int
2215dc20a302Sas200622 smb_lgrp_decode_privset(smb_group_t *grp, char *nprivs, char *privs)
2216dc20a302Sas200622 {
2217dc20a302Sas200622 	smb_lgplist_t plist;
2218dc20a302Sas200622 	int i;
2219dc20a302Sas200622 
2220dc20a302Sas200622 	plist.p_cnt = atoi(nprivs);
2221dc20a302Sas200622 	if (strlen(privs) != plist.p_cnt)
2222dc20a302Sas200622 		return (SMB_LGRP_BAD_DATA);
2223dc20a302Sas200622 
2224dc20a302Sas200622 	plist.p_ids = (smb_lgpid_t *)privs;
2225dc20a302Sas200622 	grp->sg_privs = smb_privset_new();
2226dc20a302Sas200622 	if (grp->sg_privs == NULL)
2227dc20a302Sas200622 		return (SMB_LGRP_NO_MEMORY);
2228dc20a302Sas200622 
2229dc20a302Sas200622 	for (i = 0; i < plist.p_cnt; i++)
2230dc20a302Sas200622 		smb_privset_enable(grp->sg_privs, plist.p_ids[i]);
2231dc20a302Sas200622 
2232dc20a302Sas200622 	return (SMB_LGRP_SUCCESS);
2233dc20a302Sas200622 }
2234dc20a302Sas200622 
2235dc20a302Sas200622 /*
2236dc20a302Sas200622  * smb_lgrp_decode_members
2237dc20a302Sas200622  *
2238dc20a302Sas200622  * Decodes the members information read from group table
22396537f381Sas200622  * (nmembers, members) into a binary format specified by the
2240dc20a302Sas200622  * member fields of smb_group_t
2241dc20a302Sas200622  */
2242dc20a302Sas200622 static int
2243dc20a302Sas200622 smb_lgrp_decode_members(smb_group_t *grp, char *nmembers, char *members,
2244dc20a302Sas200622     sqlite *db)
2245dc20a302Sas200622 {
22466537f381Sas200622 	smb_lgmid_t *m_id;
2247dc20a302Sas200622 	smb_lgmid_t *m_ids;
22486537f381Sas200622 	smb_gsid_t *m_sid;
22496537f381Sas200622 	smb_gsid_t *m_sids;
22506537f381Sas200622 	int m_num;
2251dc20a302Sas200622 	int mids_size;
2252dc20a302Sas200622 	int i, rc;
2253dc20a302Sas200622 
22546537f381Sas200622 	grp->sg_nmembers = 0;
22556537f381Sas200622 	grp->sg_members = NULL;
22566537f381Sas200622 
22576537f381Sas200622 	m_num = atoi(nmembers);
22586537f381Sas200622 	mids_size = m_num * sizeof (smb_lgmid_t);
22596537f381Sas200622 	if ((m_ids = malloc(mids_size)) == NULL)
2260dc20a302Sas200622 		return (SMB_LGRP_NO_MEMORY);
2261dc20a302Sas200622 
22629fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	m_sids = calloc(m_num, sizeof (smb_gsid_t));
22636537f381Sas200622 	if (m_sids == NULL) {
2264dc20a302Sas200622 		free(m_ids);
2265dc20a302Sas200622 		return (SMB_LGRP_NO_MEMORY);
2266dc20a302Sas200622 	}
2267dc20a302Sas200622 
2268dc20a302Sas200622 	(void) hextobin(members, strlen(members), (char *)m_ids, mids_size);
2269dc20a302Sas200622 
22706537f381Sas200622 	m_id = m_ids;
22716537f381Sas200622 	m_sid = m_sids;
22726537f381Sas200622 	for (i = 0; i < m_num; i++, m_id++, m_sid++) {
22736537f381Sas200622 		rc = smb_lgrp_getsid(m_id->m_idx, &m_id->m_rid, m_id->m_type,
22746537f381Sas200622 		    db, &m_sid->gs_sid);
22756537f381Sas200622 
2276dc20a302Sas200622 		if (rc != SMB_LGRP_SUCCESS) {
2277dc20a302Sas200622 			free(m_ids);
22786537f381Sas200622 			for (m_sid = m_sids; m_sid->gs_sid != NULL; m_sid++)
22796537f381Sas200622 				smb_sid_free(m_sid->gs_sid);
22806537f381Sas200622 			free(m_sids);
22816537f381Sas200622 			return (rc);
2282dc20a302Sas200622 		}
2283dc20a302Sas200622 
22846537f381Sas200622 		m_sid->gs_type = m_id->m_type;
2285dc20a302Sas200622 	}
2286dc20a302Sas200622 
2287dc20a302Sas200622 	free(m_ids);
22886537f381Sas200622 
22896537f381Sas200622 	grp->sg_nmembers = m_num;
22906537f381Sas200622 	grp->sg_members = m_sids;
2291dc20a302Sas200622 	return (SMB_LGRP_SUCCESS);
2292dc20a302Sas200622 }
2293dc20a302Sas200622 
2294dc20a302Sas200622 /*
2295dc20a302Sas200622  * smb_lgrp_decode
2296dc20a302Sas200622  *
2297dc20a302Sas200622  * Fills out the fields of the given group (grp) based in the
2298dc20a302Sas200622  * string information read from the group table. infolvl determines
2299dc20a302Sas200622  * which fields are requested and need to be decoded.
2300dc20a302Sas200622  *
2301dc20a302Sas200622  * Allocated memories must be freed by calling smb_lgrp_free()
2302dc20a302Sas200622  * upon successful return.
2303dc20a302Sas200622  */
2304dc20a302Sas200622 static int
2305dc20a302Sas200622 smb_lgrp_decode(smb_group_t *grp, char **values, int infolvl, sqlite *db)
2306dc20a302Sas200622 {
2307dc20a302Sas200622 	uint32_t sid_idx;
2308dc20a302Sas200622 	int rc;
2309dc20a302Sas200622 
2310dc20a302Sas200622 	if (infolvl == SMB_LGRP_INFO_NONE)
2311dc20a302Sas200622 		return (SMB_LGRP_SUCCESS);
2312dc20a302Sas200622 
2313dc20a302Sas200622 	if (infolvl & SMB_LGRP_INFO_NAME) {
2314dc20a302Sas200622 		grp->sg_name = strdup(values[SMB_LGRP_GTBL_NAME]);
2315dc20a302Sas200622 		if (grp->sg_name == NULL)
2316dc20a302Sas200622 			return (SMB_LGRP_NO_MEMORY);
2317dc20a302Sas200622 	}
2318dc20a302Sas200622 
2319dc20a302Sas200622 	if (infolvl & SMB_LGRP_INFO_CMNT) {
2320dc20a302Sas200622 		grp->sg_cmnt = strdup(values[SMB_LGRP_GTBL_CMNT]);
2321dc20a302Sas200622 		if (grp->sg_cmnt == NULL) {
2322dc20a302Sas200622 			smb_lgrp_free(grp);
2323dc20a302Sas200622 			return (SMB_LGRP_NO_MEMORY);
2324dc20a302Sas200622 		}
2325dc20a302Sas200622 	}
2326dc20a302Sas200622 
2327dc20a302Sas200622 
2328dc20a302Sas200622 	if (infolvl & SMB_LGRP_INFO_SID) {
2329dc20a302Sas200622 		sid_idx = atoi(values[SMB_LGRP_GTBL_SIDIDX]);
2330dc20a302Sas200622 		grp->sg_rid = atoi(values[SMB_LGRP_GTBL_SIDRID]);
2331dc20a302Sas200622 		grp->sg_attr = atoi(values[SMB_LGRP_GTBL_SIDATR]);
2332dc20a302Sas200622 		grp->sg_id.gs_type = atoi(values[SMB_LGRP_GTBL_SIDTYP]);
2333dc20a302Sas200622 		rc = smb_lgrp_getsid(sid_idx, &grp->sg_rid, grp->sg_id.gs_type,
2334dc20a302Sas200622 		    db, &grp->sg_id.gs_sid);
2335dc20a302Sas200622 		if (rc != SMB_LGRP_SUCCESS) {
2336dc20a302Sas200622 			smb_lgrp_free(grp);
23379fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			return (rc);
2338dc20a302Sas200622 		}
2339dc20a302Sas200622 		grp->sg_domain = (sid_idx == SMB_LGRP_LOCAL_IDX)
23409fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		    ? SMB_DOMAIN_LOCAL : SMB_DOMAIN_BUILTIN;
2341dc20a302Sas200622 	}
2342dc20a302Sas200622 
2343dc20a302Sas200622 	if (infolvl & SMB_LGRP_INFO_PRIV) {
2344dc20a302Sas200622 		rc = smb_lgrp_decode_privset(grp, values[SMB_LGRP_GTBL_NPRIVS],
2345dc20a302Sas200622 		    values[SMB_LGRP_GTBL_PRIVS]);
2346dc20a302Sas200622 
2347dc20a302Sas200622 		if (rc != SMB_LGRP_SUCCESS) {
2348dc20a302Sas200622 			smb_lgrp_free(grp);
2349dc20a302Sas200622 			return (rc);
2350dc20a302Sas200622 		}
2351dc20a302Sas200622 	}
2352dc20a302Sas200622 
2353dc20a302Sas200622 	if (infolvl & SMB_LGRP_INFO_MEMB) {
2354dc20a302Sas200622 		rc = smb_lgrp_decode_members(grp, values[SMB_LGRP_GTBL_NMEMBS],
2355dc20a302Sas200622 		    values[SMB_LGRP_GTBL_MEMBS], db);
2356dc20a302Sas200622 		if (rc != SMB_LGRP_SUCCESS) {
2357dc20a302Sas200622 			smb_lgrp_free(grp);
2358dc20a302Sas200622 			return (rc);
2359dc20a302Sas200622 		}
2360dc20a302Sas200622 	}
2361dc20a302Sas200622 
2362dc20a302Sas200622 	return (SMB_LGRP_SUCCESS);
2363dc20a302Sas200622 }
2364dc20a302Sas200622 
2365dc20a302Sas200622 /*
2366fe1c642dSBill Krier  * smb_lgrp_normalize_name
2367dc20a302Sas200622  *
2368fe1c642dSBill Krier  * Trim whitespace, validate the group name and convert it to lowercase.
2369dc20a302Sas200622  */
2370dc20a302Sas200622 static boolean_t
2371fe1c642dSBill Krier smb_lgrp_normalize_name(char *name)
2372dc20a302Sas200622 {
2373fe1c642dSBill Krier 	(void) trim_whitespace(name);
2374dc20a302Sas200622 
2375fe1c642dSBill Krier 	if (smb_name_validate_account(name) != ERROR_SUCCESS)
2376dc20a302Sas200622 		return (B_FALSE);
2377dc20a302Sas200622 
2378bbf6f00cSJordan Brown 	(void) smb_strlwr(name);
2379dc20a302Sas200622 	return (B_TRUE);
2380dc20a302Sas200622 }
2381dc20a302Sas200622 
2382dc20a302Sas200622 /*
2383dc20a302Sas200622  * smb_lgrp_set_default_privs
2384dc20a302Sas200622  *
2385dc20a302Sas200622  * set default privileges for Administrators and Backup Operators
2386dc20a302Sas200622  */
2387dc20a302Sas200622 static void
2388dc20a302Sas200622 smb_lgrp_set_default_privs(smb_group_t *grp)
2389dc20a302Sas200622 {
2390bbf6f00cSJordan Brown 	if (smb_strcasecmp(grp->sg_name, "Administrators", 0) == 0) {
2391dc20a302Sas200622 		smb_privset_enable(grp->sg_privs, SE_TAKE_OWNERSHIP_LUID);
2392dc20a302Sas200622 		return;
2393dc20a302Sas200622 	}
2394dc20a302Sas200622 
2395bbf6f00cSJordan Brown 	if (smb_strcasecmp(grp->sg_name, "Backup Operators", 0) == 0) {
2396dc20a302Sas200622 		smb_privset_enable(grp->sg_privs, SE_BACKUP_LUID);
2397dc20a302Sas200622 		smb_privset_enable(grp->sg_privs, SE_RESTORE_LUID);
2398dc20a302Sas200622 		return;
2399dc20a302Sas200622 	}
2400dc20a302Sas200622 }
2401dc20a302Sas200622 
2402dc20a302Sas200622 /*
2403dc20a302Sas200622  * smb_lgrp_getsid
2404dc20a302Sas200622  *
2405dc20a302Sas200622  * Returns a SID based on the provided information
2406dc20a302Sas200622  * If dom_idx is 0, it means 'rid' contains a UID/GID and the
2407dc20a302Sas200622  * returned SID will be a local SID. If dom_idx is not 0 then
2408dc20a302Sas200622  * the domain SID will be fetched from the domain table.
2409dc20a302Sas200622  */
2410dc20a302Sas200622 static int
2411dc20a302Sas200622 smb_lgrp_getsid(int dom_idx, uint32_t *rid, uint16_t sid_type,
24126537f381Sas200622     sqlite *db, smb_sid_t **sid)
2413dc20a302Sas200622 {
24146537f381Sas200622 	smb_sid_t *dom_sid = NULL;
24156537f381Sas200622 	smb_sid_t *res_sid = NULL;
24169fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	idmap_stat stat;
2417dc20a302Sas200622 	int id_type;
2418dc20a302Sas200622 	int rc;
2419dc20a302Sas200622 
2420dc20a302Sas200622 	*sid = NULL;
2421dc20a302Sas200622 	if (dom_idx == SMB_LGRP_LOCAL_IDX) {
2422dc20a302Sas200622 		id_type = (sid_type == SidTypeUser)
2423dc20a302Sas200622 		    ? SMB_IDMAP_USER : SMB_IDMAP_GROUP;
24249fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		stat = smb_idmap_getsid(*rid, id_type, &res_sid);
24259fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		if (stat != IDMAP_SUCCESS) {
24269fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			syslog(LOG_ERR, "smb_lgrp_getsid: "
24279fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			    "failed to get a SID for %s id=%u (%d)",
24289fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			    (id_type == SMB_IDMAP_USER) ? "user" : "group",
24299fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			    *rid, stat);
2430dc20a302Sas200622 			return (SMB_LGRP_NO_SID);
24319fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		}
2432dc20a302Sas200622 
2433dc20a302Sas200622 		/*
2434dc20a302Sas200622 		 * Make sure the returned SID is local
2435dc20a302Sas200622 		 */
24369fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		if (!smb_sid_indomain(smb_localgrp.lg_machine_sid, res_sid)) {
24379fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			syslog(LOG_ERR, "smb_lgrp_getsid: "
24389fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			    "local %s (%u) is mapped to a non-local SID",
24399fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			    (id_type == SMB_IDMAP_USER) ? "user" : "group",
24409fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			    *rid);
24416537f381Sas200622 			smb_sid_free(res_sid);
2442dc20a302Sas200622 			return (SMB_LGRP_SID_NOTLOCAL);
2443dc20a302Sas200622 		}
2444dc20a302Sas200622 
24456537f381Sas200622 		(void) smb_sid_getrid(res_sid, rid);
2446dc20a302Sas200622 		*sid = res_sid;
2447dc20a302Sas200622 		return (SMB_LGRP_SUCCESS);
2448dc20a302Sas200622 	}
2449dc20a302Sas200622 
2450dc20a302Sas200622 	rc = smb_lgrp_dtbl_getsid(db, dom_idx, &dom_sid);
24519fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (rc != SMB_LGRP_SUCCESS) {
24529fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		syslog(LOG_ERR, "smb_lgrp_getsid: %s", smb_lgrp_strerror(rc));
2453dc20a302Sas200622 		return (SMB_LGRP_DB_ERROR);
24549fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
2455dc20a302Sas200622 
24566537f381Sas200622 	res_sid = smb_sid_splice(dom_sid, *rid);
24576537f381Sas200622 	smb_sid_free(dom_sid);
24589fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (res_sid == NULL) {
24599fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		syslog(LOG_ERR, "smb_lgrp_getsid: %s", smb_lgrp_strerror(rc));
2460dc20a302Sas200622 		return (SMB_LGRP_NO_MEMORY);
24619fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
2462dc20a302Sas200622 
2463dc20a302Sas200622 	*sid = res_sid;
2464dc20a302Sas200622 	return (SMB_LGRP_SUCCESS);
2465dc20a302Sas200622 }
2466c8ec8eeaSjose borrego 
2467c8ec8eeaSjose borrego /*
2468c8ec8eeaSjose borrego  * smb_lgrp_getgid
2469c8ec8eeaSjose borrego  *
2470c8ec8eeaSjose borrego  * Converts given local RID to a local gid since for user
2471c8ec8eeaSjose borrego  * defined local groups, gid is stored in the table.
2472c8ec8eeaSjose borrego  */
2473c8ec8eeaSjose borrego static int
2474c8ec8eeaSjose borrego smb_lgrp_getgid(uint32_t rid, gid_t *gid)
2475c8ec8eeaSjose borrego {
2476c8ec8eeaSjose borrego 	smb_sid_t *sid;
2477c8ec8eeaSjose borrego 	int idtype;
2478c8ec8eeaSjose borrego 	int rc;
2479c8ec8eeaSjose borrego 
24809fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if ((sid = smb_sid_splice(smb_localgrp.lg_machine_sid, rid)) == NULL)
2481c8ec8eeaSjose borrego 		return (SMB_LGRP_NO_MEMORY);
2482c8ec8eeaSjose borrego 
2483c8ec8eeaSjose borrego 	idtype = SMB_IDMAP_GROUP;
2484c8ec8eeaSjose borrego 	rc = smb_idmap_getid(sid, gid, &idtype);
2485c8ec8eeaSjose borrego 	smb_sid_free(sid);
2486c8ec8eeaSjose borrego 
2487c8ec8eeaSjose borrego 	return ((rc == IDMAP_SUCCESS) ? SMB_LGRP_SUCCESS : SMB_LGRP_NOT_FOUND);
2488c8ec8eeaSjose borrego }
248929bd2886SAlan Wright 
249029bd2886SAlan Wright /*
249129bd2886SAlan Wright  * smb_lgrp_exists
249229bd2886SAlan Wright  *
249329bd2886SAlan Wright  * Returns B_TRUE if the local group with the given name exists.
249429bd2886SAlan Wright  * Otherwise, returns B_FALSE.
249529bd2886SAlan Wright  */
249629bd2886SAlan Wright static boolean_t
249729bd2886SAlan Wright smb_lgrp_exists(char *gname)
249829bd2886SAlan Wright {
249929bd2886SAlan Wright 	sqlite *db;
250029bd2886SAlan Wright 	boolean_t rc;
250129bd2886SAlan Wright 
2502fe1c642dSBill Krier 	if (!smb_lgrp_normalize_name(gname))
250329bd2886SAlan Wright 		return (B_FALSE);
250429bd2886SAlan Wright 
250529bd2886SAlan Wright 	db = smb_lgrp_db_open(SMB_LGRP_DB_ORD);
250629bd2886SAlan Wright 	if (db == NULL)
250729bd2886SAlan Wright 		return (B_FALSE);
250829bd2886SAlan Wright 
250929bd2886SAlan Wright 	rc = smb_lgrp_gtbl_exists(db, gname);
251029bd2886SAlan Wright 	smb_lgrp_db_close(db);
251129bd2886SAlan Wright 
251229bd2886SAlan Wright 	return (rc);
251329bd2886SAlan Wright }
2514148c5f43SAlan Wright 
2515148c5f43SAlan Wright /*
2516148c5f43SAlan Wright  * smb_lgrp_pgrp_valid_gname
2517148c5f43SAlan Wright  *
2518148c5f43SAlan Wright  * Validate posix group name string.
2519148c5f43SAlan Wright  */
2520148c5f43SAlan Wright static int
2521148c5f43SAlan Wright smb_lgrp_pgrp_valid_gname(char *group)
2522148c5f43SAlan Wright {
2523148c5f43SAlan Wright 	char *ptr = group;
2524148c5f43SAlan Wright 	char c;
2525148c5f43SAlan Wright 	int len = 0;
2526148c5f43SAlan Wright 	int badchar = 0;
2527148c5f43SAlan Wright 
2528148c5f43SAlan Wright 	if (!group || !*group)
2529148c5f43SAlan Wright 		return (SMB_LGRP_PGRP_INVALID);
2530148c5f43SAlan Wright 
2531148c5f43SAlan Wright 	for (c = *ptr; c != NULL; ptr++, c = *ptr) {
2532148c5f43SAlan Wright 		len++;
2533148c5f43SAlan Wright 		if (!isprint(c) || (c == ':') || (c == '\n'))
2534148c5f43SAlan Wright 			return (SMB_LGRP_PGRP_INVALID);
2535148c5f43SAlan Wright 
2536148c5f43SAlan Wright 		if (!(islower(c) || isdigit(c)))
2537148c5f43SAlan Wright 			badchar++;
2538148c5f43SAlan Wright 	}
2539148c5f43SAlan Wright 
2540148c5f43SAlan Wright 	if ((len > SMB_LGRP_PGRP_MAXGLEN - 1) || (badchar != 0))
2541148c5f43SAlan Wright 		return (SMB_LGRP_PGRP_INVALID);
2542148c5f43SAlan Wright 
2543148c5f43SAlan Wright 	if (getgrnam(group) != NULL)
2544148c5f43SAlan Wright 		return (SMB_LGRP_PGRP_NOTUNIQUE);
2545148c5f43SAlan Wright 
2546148c5f43SAlan Wright 	return (SMB_LGRP_PGRP_UNIQUE);
2547148c5f43SAlan Wright }
2548148c5f43SAlan Wright 
2549148c5f43SAlan Wright /*
2550148c5f43SAlan Wright  * smb_lgrp_pgrp_add
2551148c5f43SAlan Wright  *
2552148c5f43SAlan Wright  * Create a posix group with the given name.
2553148c5f43SAlan Wright  * This group will be added to the /etc/group file.
2554148c5f43SAlan Wright  */
2555148c5f43SAlan Wright static int
2556148c5f43SAlan Wright smb_lgrp_pgrp_add(char *group)
2557148c5f43SAlan Wright {
2558148c5f43SAlan Wright 	FILE *etcgrp;
2559148c5f43SAlan Wright 	FILE *etctmp;
2560*a7fe1d5bSAndy Stormont 	int o_mask;
2561148c5f43SAlan Wright 	int newdone = 0;
2562148c5f43SAlan Wright 	struct stat sb;
2563148c5f43SAlan Wright 	char buf[SMB_LGRP_PGRP_GRPBUFSIZ];
2564148c5f43SAlan Wright 	gid_t gid;
2565148c5f43SAlan Wright 	int rc = 0;
2566148c5f43SAlan Wright 
2567148c5f43SAlan Wright 	rc = smb_lgrp_pgrp_valid_gname(group);
2568148c5f43SAlan Wright 	if ((rc == SMB_LGRP_PGRP_INVALID) || (rc == SMB_LGRP_PGRP_NOTUNIQUE))
2569148c5f43SAlan Wright 		return (-1);
2570148c5f43SAlan Wright 
2571*a7fe1d5bSAndy Stormont 	if ((findnextgid(SMB_LGRP_PGRP_DEFRID, MAXUID, &gid)) != 0)
2572148c5f43SAlan Wright 		return (-1);
2573148c5f43SAlan Wright 
2574148c5f43SAlan Wright 	if ((etcgrp = fopen(SMB_LGRP_PGRP_GROUP, "r")) == NULL)
2575148c5f43SAlan Wright 		return (-1);
2576148c5f43SAlan Wright 
2577148c5f43SAlan Wright 	if (fstat(fileno(etcgrp), &sb) < 0)
2578148c5f43SAlan Wright 		sb.st_mode = S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH;
2579148c5f43SAlan Wright 
2580148c5f43SAlan Wright 	o_mask = umask(077);
2581148c5f43SAlan Wright 	etctmp = fopen(SMB_LGRP_PGRP_GRPTMP, "w+");
2582148c5f43SAlan Wright 	(void) umask(o_mask);
2583148c5f43SAlan Wright 
2584148c5f43SAlan Wright 	if (etctmp == NULL) {
2585148c5f43SAlan Wright 		(void) fclose(etcgrp);
2586148c5f43SAlan Wright 		return (-1);
2587148c5f43SAlan Wright 	}
2588148c5f43SAlan Wright 
2589148c5f43SAlan Wright 	if (lockf(fileno(etctmp), F_LOCK, 0) != 0) {
2590148c5f43SAlan Wright 		(void) fclose(etcgrp);
2591148c5f43SAlan Wright 		(void) fclose(etctmp);
2592148c5f43SAlan Wright 		(void) unlink(SMB_LGRP_PGRP_GRPTMP);
2593148c5f43SAlan Wright 		return (-1);
2594148c5f43SAlan Wright 	}
2595148c5f43SAlan Wright 
2596148c5f43SAlan Wright 	if (fchmod(fileno(etctmp), sb.st_mode) != 0 ||
2597148c5f43SAlan Wright 	    fchown(fileno(etctmp), sb.st_uid, sb.st_gid) != 0) {
2598148c5f43SAlan Wright 		(void) lockf(fileno(etctmp), F_ULOCK, 0);
2599148c5f43SAlan Wright 		(void) fclose(etcgrp);
2600148c5f43SAlan Wright 		(void) fclose(etctmp);
2601148c5f43SAlan Wright 		(void) unlink(SMB_LGRP_PGRP_GRPTMP);
2602148c5f43SAlan Wright 		return (-1);
2603148c5f43SAlan Wright 	}
2604148c5f43SAlan Wright 
2605148c5f43SAlan Wright 	while (fgets(buf, SMB_LGRP_PGRP_GRPBUFSIZ, etcgrp) != NULL) {
2606148c5f43SAlan Wright 		/* Check for NameService reference */
2607148c5f43SAlan Wright 		if (!newdone && (buf[0] == '+' || buf[0] == '-')) {
2608148c5f43SAlan Wright 			(void) fprintf(etctmp, "%s::%u:\n", group, gid);
2609148c5f43SAlan Wright 			newdone = 1;
2610148c5f43SAlan Wright 		}
2611148c5f43SAlan Wright 
2612148c5f43SAlan Wright 		(void) fputs(buf, etctmp);
2613148c5f43SAlan Wright 	}
2614148c5f43SAlan Wright 	(void) fclose(etcgrp);
2615148c5f43SAlan Wright 
2616148c5f43SAlan Wright 	if (!newdone)
2617148c5f43SAlan Wright 		(void) fprintf(etctmp, "%s::%u:\n", group, gid);
2618148c5f43SAlan Wright 
2619148c5f43SAlan Wright 	if (rename(SMB_LGRP_PGRP_GRPTMP, SMB_LGRP_PGRP_GROUP) < 0) {
2620148c5f43SAlan Wright 		(void) lockf(fileno(etctmp), F_ULOCK, 0);
2621148c5f43SAlan Wright 		(void) fclose(etctmp);
2622148c5f43SAlan Wright 		(void) unlink(SMB_LGRP_PGRP_GRPTMP);
2623148c5f43SAlan Wright 		return (-1);
2624148c5f43SAlan Wright 	}
2625148c5f43SAlan Wright 
2626148c5f43SAlan Wright 	(void) lockf(fileno(etctmp), F_ULOCK, 0);
2627148c5f43SAlan Wright 	(void) fclose(etctmp);
2628148c5f43SAlan Wright 	return (0);
2629148c5f43SAlan Wright }
2630