1dc20a302Sas /*
2dc20a302Sas  * CDDL HEADER START
3dc20a302Sas  *
4dc20a302Sas  * The contents of this file are subject to the terms of the
5dc20a302Sas  * Common Development and Distribution License (the "License").
6dc20a302Sas  * You may not use this file except in compliance with the License.
7dc20a302Sas  *
8dc20a302Sas  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9dc20a302Sas  * or http://www.opensolaris.org/os/licensing.
10dc20a302Sas  * See the License for the specific language governing permissions
11dc20a302Sas  * and limitations under the License.
12dc20a302Sas  *
13dc20a302Sas  * When distributing Covered Code, include this CDDL HEADER in each
14dc20a302Sas  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15dc20a302Sas  * If applicable, add the following below this CDDL HEADER, with the
16dc20a302Sas  * fields enclosed by brackets "[]" replaced with your own identifying
17dc20a302Sas  * information: Portions Copyright [yyyy] [name of copyright owner]
18dc20a302Sas  *
19dc20a302Sas  * CDDL HEADER END
20dc20a302Sas  */
21148c5f43SAlan Wright 
22dc20a302Sas /*
23c5866007SKeyur Desai  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
24a7fe1d5bSAndy Stormont  * Copyright (c) 2013 RackTop Systems.
25*3c1aa884SMatt Barden  * Copyright 2019 Nexenta by DDN, Inc. All rights reserved.
26dc20a302Sas  */
27dc20a302Sas 
28dc20a302Sas #include <stdlib.h>
29dc20a302Sas #include <strings.h>
30dc20a302Sas #include <unistd.h>
31dc20a302Sas #include <syslog.h>
32dc20a302Sas #include <thread.h>
33dc20a302Sas #include <synch.h>
34dc20a302Sas #include <grp.h>
35dc20a302Sas #include <assert.h>
36dc20a302Sas #include <libintl.h>
37dc20a302Sas #include <smbsrv/libsmb.h>
387b59d02dSjb #include <smb_sqlite.h>
39148c5f43SAlan Wright #include <sys/types.h>
40148c5f43SAlan Wright #include <sys/stat.h>
41148c5f43SAlan Wright #include <sys/param.h>
42a7fe1d5bSAndy Stormont #include <libcmdutils.h>
43dc20a302Sas 
44faa1795aSjb /*
45faa1795aSjb  * Local domain SID (aka machine SID) is not stored in the domain table
46faa1795aSjb  * therefore the index is 0
47faa1795aSjb  */
48dc20a302Sas #define	SMB_LGRP_LOCAL_IDX	0
49dc20a302Sas #define	SMB_LGRP_BUILTIN_IDX	1
50dc20a302Sas 
51dc20a302Sas #define	SMB_LGRP_DB_NAME	"/var/smb/smbgroup.db"
52dc20a302Sas #define	SMB_LGRP_DB_TIMEOUT	3000		/* in millisecond */
53dc20a302Sas #define	SMB_LGRP_DB_VERMAJOR	1
54dc20a302Sas #define	SMB_LGRP_DB_VERMINOR	0
55dc20a302Sas #define	SMB_LGRP_DB_MAGIC	0x4C475250	/* LGRP */
56dc20a302Sas 
57dc20a302Sas #define	SMB_LGRP_DB_ORD		1		/* open read-only */
58dc20a302Sas #define	SMB_LGRP_DB_ORW		2		/* open read/write */
59dc20a302Sas 
60dc20a302Sas #define	SMB_LGRP_DB_ADDMEMBER	1
61dc20a302Sas #define	SMB_LGRP_DB_DELMEMBER	2
62dc20a302Sas 
63dc20a302Sas /*
64dc20a302Sas  * members column of the groups table is an array of
65dc20a302Sas  * member structure smb_lgmid_t defined below.
66dc20a302Sas  *
67dc20a302Sas  * privs column of the groups table is an array of bytes
68dc20a302Sas  * where each byte is the id of an enable privilege
69dc20a302Sas  */
70dc20a302Sas #define	SMB_LGRP_DB_SQL \
71dc20a302Sas 	"CREATE TABLE db_info ("				\
72dc20a302Sas 	"	ver_major INTEGER,"				\
73dc20a302Sas 	"	ver_minor INTEGER,"				\
74dc20a302Sas 	"	magic     INTEGER"				\
75dc20a302Sas 	");"							\
76dc20a302Sas 	""							\
77dc20a302Sas 	"CREATE TABLE domains ("				\
78dc20a302Sas 	"	dom_idx INTEGER PRIMARY KEY,"			\
79dc20a302Sas 	"	dom_sid TEXT UNIQUE,"				\
80dc20a302Sas 	"       dom_cnt INTEGER"				\
81dc20a302Sas 	");"							\
82dc20a302Sas 	""							\
83dc20a302Sas 	"CREATE UNIQUE INDEX domsid_idx ON domains (dom_sid);"	\
84dc20a302Sas 	""							\
85dc20a302Sas 	"CREATE TABLE groups ("					\
86dc20a302Sas 	"	name      TEXT PRIMARY KEY,"			\
87dc20a302Sas 	"	sid_idx   INTEGER,"				\
88dc20a302Sas 	"	sid_rid   INTEGER,"				\
89dc20a302Sas 	"	sid_type  INTEGER,"				\
90dc20a302Sas 	"	sid_attrs INTEGER,"				\
91dc20a302Sas 	"	comment   TEXT,"				\
92dc20a302Sas 	"	n_privs   INTEGER,"				\
93dc20a302Sas 	"	privs     BLOB,"				\
94dc20a302Sas 	"	n_members INTEGER,"				\
95dc20a302Sas 	"	members   BLOB"					\
96dc20a302Sas 	");"							\
97dc20a302Sas 	""							\
98dc20a302Sas 	"CREATE INDEX grprid_idx ON groups (sid_rid);"
99dc20a302Sas 
100dc20a302Sas /*
101dc20a302Sas  * Number of groups table columns
102dc20a302Sas  */
103dc20a302Sas #define	SMB_LGRP_GTBL_NCOL	10
104dc20a302Sas 
105dc20a302Sas #define	SMB_LGRP_GTBL_NAME	0
106dc20a302Sas #define	SMB_LGRP_GTBL_SIDIDX	1
107dc20a302Sas #define	SMB_LGRP_GTBL_SIDRID	2
108dc20a302Sas #define	SMB_LGRP_GTBL_SIDTYP	3
109dc20a302Sas #define	SMB_LGRP_GTBL_SIDATR	4
110dc20a302Sas #define	SMB_LGRP_GTBL_CMNT	5
111dc20a302Sas #define	SMB_LGRP_GTBL_NPRIVS	6
112dc20a302Sas #define	SMB_LGRP_GTBL_PRIVS	7
113dc20a302Sas #define	SMB_LGRP_GTBL_NMEMBS	8
114dc20a302Sas #define	SMB_LGRP_GTBL_MEMBS	9
115dc20a302Sas 
116dc20a302Sas #define	SMB_LGRP_INFO_NONE	0x00
117dc20a302Sas #define	SMB_LGRP_INFO_NAME	0x01
118dc20a302Sas #define	SMB_LGRP_INFO_CMNT	0x02
119dc20a302Sas #define	SMB_LGRP_INFO_SID	0x04
120dc20a302Sas #define	SMB_LGRP_INFO_PRIV	0x08
121dc20a302Sas #define	SMB_LGRP_INFO_MEMB	0x10
122dc20a302Sas #define	SMB_LGRP_INFO_ALL	0x1F
123dc20a302Sas 
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 */
128a7fe1d5bSAndy 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 
136dc20a302Sas #define	NULL_MSGCHK(msg)	((msg) ? (msg) : "NULL")
137dc20a302Sas 
138dc20a302Sas /* Member ID */
139dc20a302Sas typedef struct smb_lgmid {
140dc20a302Sas 	uint32_t m_idx;
141dc20a302Sas 	uint32_t m_rid;
142dc20a302Sas 	uint16_t m_type;
143dc20a302Sas } smb_lgmid_t;
144dc20a302Sas 
145d4c7367eSGordon Ross /* Buffer size to hold hex form of the above (>24). */
146dc20a302Sas #define	SMB_LGRP_MID_HEXSZ	32
147dc20a302Sas 
148d4c7367eSGordon Ross /* Size of idx,rid parts of above, in hex form. */
149d4c7367eSGordon Ross #define	SMB_LGRP_IDXRID_LEN	16
150d4c7367eSGordon Ross 
151dc20a302Sas /* Member list */
152dc20a302Sas typedef struct smb_lgmlist {
153dc20a302Sas 	uint32_t	m_cnt;
154dc20a302Sas 	char		*m_ids;
155dc20a302Sas } smb_lgmlist_t;
156dc20a302Sas 
157dc20a302Sas /* Privilege ID */
158dc20a302Sas typedef uint8_t smb_lgpid_t;
159dc20a302Sas 
160dc20a302Sas /* Privilege list */
161dc20a302Sas typedef struct smb_lgplist {
162dc20a302Sas 	uint32_t	p_cnt;
163dc20a302Sas 	smb_lgpid_t	*p_ids;
164dc20a302Sas } smb_lgplist_t;
165dc20a302Sas 
1669fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static struct {
1679fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	int	errnum;
1689fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	char	*errmsg;
1699fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } errtab[] = {
1709fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	{ SMB_LGRP_SUCCESS,		"success" },
1719fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	{ SMB_LGRP_INVALID_ARG,		"invalid argument" },
1729fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	{ SMB_LGRP_INVALID_MEMBER,	"invalid member type" },
1739fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	{ SMB_LGRP_INVALID_NAME,	"invalid name" },
1749fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	{ SMB_LGRP_NOT_FOUND,		"group not found" },
1759fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	{ SMB_LGRP_EXISTS,		"group exists" },
1769fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	{ SMB_LGRP_NO_SID,		"cannot obtain a SID" },
1779fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	{ SMB_LGRP_NO_LOCAL_SID,	"cannot get the machine SID" },
1789fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	{ SMB_LGRP_SID_NOTLOCAL,	"local account has non-local SID" },
1799fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	{ SMB_LGRP_WKSID,
1809fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		"operation not permitted on well-known account" },
1819fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	{ SMB_LGRP_NO_MEMORY,		"not enough memory" },
1829fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	{ SMB_LGRP_DB_ERROR,		"database operation error" },
1839fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	{ SMB_LGRP_DBINIT_ERROR,	"database initialization error" },
1849fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	{ SMB_LGRP_INTERNAL_ERROR,	"internal error" },
1859fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	{ SMB_LGRP_MEMBER_IN_GROUP,	"member already in group" },
1869fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	{ SMB_LGRP_MEMBER_NOT_IN_GROUP,	"not a member" },
1879fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	{ SMB_LGRP_NO_SUCH_PRIV,	"no such privilege" },
1889fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	{ SMB_LGRP_NO_SUCH_DOMAIN,	"no such domain SID" },
1899fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	{ SMB_LGRP_PRIV_HELD,		"privilege already held" },
1909fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	{ SMB_LGRP_PRIV_NOT_HELD,	"privilege not held" },
1919fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	{ SMB_LGRP_BAD_DATA,		"bad data" },
1929fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	{ SMB_LGRP_NO_MORE,		"no more groups" },
1939fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	{ SMB_LGRP_DBOPEN_FAILED,	"database open failed" },
1949fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	{ SMB_LGRP_DBEXEC_FAILED,	"database operation failed" },
1959fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	{ SMB_LGRP_DBINIT_FAILED,	"database initialization failed" },
1969fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	{ SMB_LGRP_DOMLKP_FAILED,	"domain SID lookup failed" },
1979fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	{ SMB_LGRP_DOMINS_FAILED,	"domain SID insert failed" },
1989fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	{ SMB_LGRP_INSERT_FAILED,	"group insert failed" },
1999fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	{ SMB_LGRP_DELETE_FAILED,	"group delete failed" },
2009fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	{ SMB_LGRP_UPDATE_FAILED,	"group update failed" },
2019fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	{ SMB_LGRP_LOOKUP_FAILED,	"group lookup failed" },
202148c5f43SAlan Wright 	{ SMB_LGRP_OFFLINE,		"local group service is offline" },
203148c5f43SAlan Wright 	{ SMB_LGRP_POSIXCREATE_FAILED,	"posix group create failed" }
2049fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States };
205dc20a302Sas 
2069fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
2079fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Serialization for the local group API.
2089fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
2099fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States typedef struct {
2109fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	mutex_t		lg_mutex;
2119fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	cond_t		lg_cv;
2129fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	boolean_t	lg_online;
2139fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	uint32_t	lg_refcnt;
2149fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_sid_t	*lg_machine_sid;
2159fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } smb_localgrp_t;
2169fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
2179fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static smb_localgrp_t smb_localgrp;
2189fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
2199fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static boolean_t smb_lgrp_enter(void);
2209fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static void smb_lgrp_exit(void);
221dc20a302Sas static int smb_lgrp_db_init(void);
222dc20a302Sas static sqlite *smb_lgrp_db_open(int);
223dc20a302Sas static void smb_lgrp_db_close(sqlite *);
224dc20a302Sas static int smb_lgrp_db_setinfo(sqlite *);
225dc20a302Sas 
226dc20a302Sas static boolean_t smb_lgrp_gtbl_exists(sqlite *, char *);
227dc20a302Sas static int smb_lgrp_gtbl_lookup(sqlite *, int, smb_group_t *, int, ...);
228dc20a302Sas static int smb_lgrp_gtbl_insert(sqlite *, smb_group_t *);
229dc20a302Sas static int smb_lgrp_gtbl_update(sqlite *, char *, smb_group_t *, int);
230dc20a302Sas static int smb_lgrp_gtbl_delete(sqlite *, char *);
231dc20a302Sas static int smb_lgrp_gtbl_update_mlist(sqlite *, char *, smb_gsid_t *, int);
232dc20a302Sas static int smb_lgrp_gtbl_update_plist(sqlite *, char *, uint8_t, boolean_t);
233dc20a302Sas static int smb_lgrp_gtbl_count(sqlite *, int, int *);
234dc20a302Sas 
235dc20a302Sas static int smb_lgrp_dtbl_insert(sqlite *, char *, uint32_t *);
2366537f381Sas static int smb_lgrp_dtbl_getidx(sqlite *, smb_sid_t *, uint16_t,
237dc20a302Sas     uint32_t *, uint32_t *);
2386537f381Sas static int smb_lgrp_dtbl_getsid(sqlite *, uint32_t, smb_sid_t **);
239dc20a302Sas 
240dc20a302Sas static int smb_lgrp_mlist_add(smb_lgmlist_t *, smb_lgmid_t *, smb_lgmlist_t *);
241dc20a302Sas static int smb_lgrp_mlist_del(smb_lgmlist_t *, smb_lgmid_t *, smb_lgmlist_t *);
242dc20a302Sas 
243dc20a302Sas static int smb_lgrp_plist_add(smb_lgplist_t *, smb_lgpid_t, smb_lgplist_t *);
244dc20a302Sas static int smb_lgrp_plist_del(smb_lgplist_t *, smb_lgpid_t, smb_lgplist_t *);
245dc20a302Sas 
246dc20a302Sas static void smb_lgrp_encode_privset(smb_group_t *, smb_lgplist_t *);
247dc20a302Sas 
248dc20a302Sas static int smb_lgrp_decode(smb_group_t *, char **, int, sqlite *);
249dc20a302Sas static int smb_lgrp_decode_privset(smb_group_t *, char *, char *);
250dc20a302Sas static int smb_lgrp_decode_members(smb_group_t *, char *, char *, sqlite *);
251dc20a302Sas 
252dc20a302Sas static void smb_lgrp_set_default_privs(smb_group_t *);
253fe1c642dSBill Krier static boolean_t smb_lgrp_normalize_name(char *);
254dc20a302Sas static boolean_t smb_lgrp_chkmember(uint16_t);
2556537f381Sas static int smb_lgrp_getsid(int, uint32_t *, uint16_t, sqlite *, smb_sid_t **);
256c8ec8eeaSjose borrego static int smb_lgrp_getgid(uint32_t rid, gid_t *gid);
25729bd2886SAlan Wright static boolean_t smb_lgrp_exists(char *);
258148c5f43SAlan Wright static int smb_lgrp_pgrp_add(char *);
259dc20a302Sas 
260dc20a302Sas /*
261dc20a302Sas  * smb_lgrp_add
262dc20a302Sas  *
263dc20a302Sas  * Create a local group with the given name and comment.
264dc20a302Sas  * This new group doesn't have any members and no enabled
265dc20a302Sas  * privileges.
266dc20a302Sas  *
267dc20a302Sas  * No well-known accounts can be added other than Administators,
268dc20a302Sas  * Backup Operators and Power Users. These built-in groups
269dc20a302Sas  * won't have any members when created but a set of default
270dc20a302Sas  * privileges will be enabled for them.
271dc20a302Sas  */
272dc20a302Sas int
smb_lgrp_add(char * gname,char * cmnt)273dc20a302Sas smb_lgrp_add(char *gname, char *cmnt)
274dc20a302Sas {
2756537f381Sas 	smb_wka_t *wka;
276dc20a302Sas 	struct group *pxgrp;
277dc20a302Sas 	smb_group_t grp;
2786537f381Sas 	smb_sid_t *sid = NULL;
279dc20a302Sas 	sqlite *db;
280dc20a302Sas 	int rc;
281dc20a302Sas 
282fe1c642dSBill Krier 	if (!smb_lgrp_normalize_name(gname))
283dc20a302Sas 		return (SMB_LGRP_INVALID_NAME);
284dc20a302Sas 
285dc20a302Sas 	if (cmnt && (strlen(cmnt) > SMB_LGRP_COMMENT_MAX))
286dc20a302Sas 		return (SMB_LGRP_INVALID_ARG);
287dc20a302Sas 
288dc20a302Sas 	bzero(&grp, sizeof (grp));
289bbf6f00cSJordan Brown 	grp.sg_name = smb_strlwr(gname);
290dc20a302Sas 	grp.sg_cmnt = cmnt;
291dc20a302Sas 
2929fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (!smb_lgrp_enter())
2939fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (SMB_LGRP_OFFLINE);
2949fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
2957f667e74Sjose borrego 	wka = smb_wka_lookup_name(gname);
2966537f381Sas 	if (wka == NULL) {
2979fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		if ((pxgrp = getgrnam(gname)) == NULL) {
298148c5f43SAlan Wright 			if (smb_lgrp_pgrp_add(gname) != 0) {
299148c5f43SAlan Wright 				smb_lgrp_exit();
300148c5f43SAlan Wright 				return (SMB_LGRP_POSIXCREATE_FAILED);
301148c5f43SAlan Wright 			}
302148c5f43SAlan Wright 
303148c5f43SAlan Wright 			if ((pxgrp = getgrnam(gname)) == NULL) {
304148c5f43SAlan Wright 				smb_lgrp_exit();
305148c5f43SAlan Wright 				return (SMB_LGRP_NOT_FOUND);
306148c5f43SAlan Wright 			}
3079fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		}
308dc20a302Sas 
309dc20a302Sas 		/*
310dc20a302Sas 		 * Make sure a local SID can be obtained
311dc20a302Sas 		 */
312dc20a302Sas 		if (smb_idmap_getsid(pxgrp->gr_gid, SMB_IDMAP_GROUP, &sid)
3139fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		    != IDMAP_SUCCESS) {
3149fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			smb_lgrp_exit();
315dc20a302Sas 			return (SMB_LGRP_NO_SID);
3169fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		}
317dc20a302Sas 
3189fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		if (!smb_sid_indomain(smb_localgrp.lg_machine_sid, sid)) {
319dc20a302Sas 			free(sid);
3209fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			smb_lgrp_exit();
321dc20a302Sas 			return (SMB_LGRP_SID_NOTLOCAL);
322dc20a302Sas 		}
323dc20a302Sas 
3249fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		free(sid);
325dc20a302Sas 		grp.sg_id.gs_type = SidTypeAlias;
3269fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		grp.sg_domain = SMB_DOMAIN_LOCAL;
327dc20a302Sas 		grp.sg_rid = pxgrp->gr_gid;
328dc20a302Sas 	} else {
3296537f381Sas 		if ((wka->wka_flags & SMB_WKAFLG_LGRP_ENABLE) == 0) {
330dc20a302Sas 			/* cannot add well-known accounts */
3319fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			smb_lgrp_exit();
332dc20a302Sas 			return (SMB_LGRP_WKSID);
333dc20a302Sas 		}
334dc20a302Sas 
3356537f381Sas 		grp.sg_id.gs_type = wka->wka_type;
3369fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		if ((sid = smb_sid_fromstr(wka->wka_sid)) == NULL) {
3379fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			smb_lgrp_exit();
338dc20a302Sas 			return (SMB_LGRP_NO_MEMORY);
3399fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		}
3409fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
3416537f381Sas 		(void) smb_sid_getrid(sid, &grp.sg_rid);
342dc20a302Sas 		free(sid);
3439fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		grp.sg_domain = SMB_DOMAIN_BUILTIN;
344dc20a302Sas 		grp.sg_privs = smb_privset_new();
345dc20a302Sas 		smb_lgrp_set_default_privs(&grp);
346dc20a302Sas 	}
347dc20a302Sas 
3489fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (smb_lgrp_exists(grp.sg_name)) {
3499fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		smb_lgrp_exit();
35096a62adaSjoyce mcintosh 		return (SMB_LGRP_EXISTS);
3519fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
352dc20a302Sas 
353dc20a302Sas 	grp.sg_attr = SE_GROUP_MANDATORY | SE_GROUP_ENABLED_BY_DEFAULT |
354dc20a302Sas 	    SE_GROUP_ENABLED;
355dc20a302Sas 
356dc20a302Sas 	db = smb_lgrp_db_open(SMB_LGRP_DB_ORW);
357dc20a302Sas 	rc = smb_lgrp_gtbl_insert(db, &grp);
358dc20a302Sas 	smb_lgrp_db_close(db);
359dc20a302Sas 
360dc20a302Sas 	smb_privset_free(grp.sg_privs);
3619fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_lgrp_exit();
362dc20a302Sas 	return (rc);
363dc20a302Sas }
364dc20a302Sas 
365dc20a302Sas /*
366dc20a302Sas  * smb_lgrp_rename
367dc20a302Sas  *
368dc20a302Sas  * Renames the given group
369dc20a302Sas  */
370dc20a302Sas int
smb_lgrp_rename(char * gname,char * new_gname)371dc20a302Sas smb_lgrp_rename(char *gname, char *new_gname)
372dc20a302Sas {
373dc20a302Sas 	smb_group_t grp;
374dc20a302Sas 	sqlite *db;
375dc20a302Sas 	int rc;
376dc20a302Sas 
377fe1c642dSBill Krier 	if (!smb_lgrp_normalize_name(gname))
378dc20a302Sas 		return (SMB_LGRP_INVALID_NAME);
379dc20a302Sas 
380fe1c642dSBill Krier 	if (!smb_lgrp_normalize_name(gname))
381dc20a302Sas 		return (SMB_LGRP_INVALID_NAME);
382dc20a302Sas 
383bbf6f00cSJordan Brown 	if (smb_strcasecmp(gname, new_gname, 0) == 0)
384dc20a302Sas 		return (SMB_LGRP_SUCCESS);
385dc20a302Sas 
386dc20a302Sas 	/* Cannot rename well-known groups */
3877f667e74Sjose borrego 	if (smb_wka_lookup_name(gname) != NULL)
388dc20a302Sas 		return (SMB_LGRP_WKSID);
389dc20a302Sas 
390dc20a302Sas 	/* Cannot rename to a well-known groups */
3917f667e74Sjose borrego 	if (smb_wka_lookup_name(new_gname) != NULL)
392dc20a302Sas 		return (SMB_LGRP_WKSID);
393dc20a302Sas 
394dc20a302Sas 	grp.sg_name = new_gname;
395dc20a302Sas 
3969fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (!smb_lgrp_enter())
3979fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (SMB_LGRP_OFFLINE);
3989fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
399148c5f43SAlan Wright 	if (getgrnam(new_gname) == NULL) {
400148c5f43SAlan Wright 		if (smb_lgrp_pgrp_add(new_gname) != 0) {
401148c5f43SAlan Wright 			smb_lgrp_exit();
402148c5f43SAlan Wright 			return (SMB_LGRP_POSIXCREATE_FAILED);
403148c5f43SAlan Wright 		}
404148c5f43SAlan Wright 
405148c5f43SAlan Wright 		if (getgrnam(new_gname) == NULL) {
406148c5f43SAlan Wright 			smb_lgrp_exit();
407148c5f43SAlan Wright 			return (SMB_LGRP_NOT_FOUND);
408148c5f43SAlan Wright 		}
409148c5f43SAlan Wright 	}
410148c5f43SAlan Wright 
411dc20a302Sas 	db = smb_lgrp_db_open(SMB_LGRP_DB_ORW);
412dc20a302Sas 	rc = smb_lgrp_gtbl_update(db, gname, &grp, SMB_LGRP_GTBL_NAME);
413dc20a302Sas 	smb_lgrp_db_close(db);
414dc20a302Sas 
4159fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_lgrp_exit();
416dc20a302Sas 	return (rc);
417dc20a302Sas }
418dc20a302Sas 
419dc20a302Sas /*
420dc20a302Sas  * smb_lgrp_delete
421dc20a302Sas  *
422dc20a302Sas  * Deletes the specified local group.
423dc20a302Sas  */
424dc20a302Sas int
smb_lgrp_delete(char * gname)425dc20a302Sas smb_lgrp_delete(char *gname)
426dc20a302Sas {
427dc20a302Sas 	sqlite *db;
428dc20a302Sas 	int rc;
429dc20a302Sas 
430fe1c642dSBill Krier 	if (!smb_lgrp_normalize_name(gname))
431dc20a302Sas 		return (SMB_LGRP_INVALID_NAME);
432dc20a302Sas 
433dc20a302Sas 	/* Cannot remove a built-in group */
4347f667e74Sjose borrego 	if (smb_wka_lookup_name(gname) != NULL)
435dc20a302Sas 		return (SMB_LGRP_WKSID);
436dc20a302Sas 
43796a62adaSjoyce mcintosh 
43896a62adaSjoyce mcintosh 	if (!smb_lgrp_exists(gname))
43996a62adaSjoyce mcintosh 		return (SMB_LGRP_NOT_FOUND);
44096a62adaSjoyce mcintosh 
4419fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (!smb_lgrp_enter())
4429fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (SMB_LGRP_OFFLINE);
4439fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
444dc20a302Sas 	db = smb_lgrp_db_open(SMB_LGRP_DB_ORW);
445dc20a302Sas 	rc = smb_lgrp_gtbl_delete(db, gname);
446dc20a302Sas 	smb_lgrp_db_close(db);
447dc20a302Sas 
4489fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_lgrp_exit();
449dc20a302Sas 	return (rc);
450dc20a302Sas }
451dc20a302Sas 
452dc20a302Sas /*
453dc20a302Sas  * smb_lgrp_setcmnt
454dc20a302Sas  *
455dc20a302Sas  * Sets the description for the given group
456dc20a302Sas  */
457dc20a302Sas int
smb_lgrp_setcmnt(char * gname,char * cmnt)458dc20a302Sas smb_lgrp_setcmnt(char *gname, char *cmnt)
459dc20a302Sas {
460dc20a302Sas 	smb_group_t grp;
461dc20a302Sas 	sqlite *db;
462dc20a302Sas 	int rc;
463dc20a302Sas 
464fe1c642dSBill Krier 	if (!smb_lgrp_normalize_name(gname))
465dc20a302Sas 		return (SMB_LGRP_INVALID_NAME);
466dc20a302Sas 
467dc20a302Sas 	if (cmnt && (strlen(cmnt) > SMB_LGRP_COMMENT_MAX))
468dc20a302Sas 		return (SMB_LGRP_INVALID_ARG);
469dc20a302Sas 
470dc20a302Sas 	grp.sg_cmnt = cmnt;
471dc20a302Sas 
4729fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (!smb_lgrp_enter())
4739fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (SMB_LGRP_OFFLINE);
4749fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
475dc20a302Sas 	db = smb_lgrp_db_open(SMB_LGRP_DB_ORW);
476dc20a302Sas 	rc = smb_lgrp_gtbl_update(db, gname, &grp, SMB_LGRP_GTBL_CMNT);
477dc20a302Sas 	smb_lgrp_db_close(db);
478dc20a302Sas 
4799fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_lgrp_exit();
480dc20a302Sas 	return (rc);
481dc20a302Sas }
482dc20a302Sas 
483dc20a302Sas /*
484dc20a302Sas  * smb_lgrp_getcmnt
485dc20a302Sas  *
486dc20a302Sas  * Obtain the description of the specified group
487dc20a302Sas  */
488dc20a302Sas int
smb_lgrp_getcmnt(char * gname,char ** cmnt)489dc20a302Sas smb_lgrp_getcmnt(char *gname, char **cmnt)
490dc20a302Sas {
491dc20a302Sas 	smb_group_t grp;
492dc20a302Sas 	sqlite *db;
493dc20a302Sas 	int rc;
494dc20a302Sas 
495fe1c642dSBill Krier 	if (!smb_lgrp_normalize_name(gname))
496dc20a302Sas 		return (SMB_LGRP_INVALID_NAME);
497dc20a302Sas 
498dc20a302Sas 	if (cmnt == NULL)
499dc20a302Sas 		return (SMB_LGRP_INVALID_ARG);
500dc20a302Sas 
5019fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (!smb_lgrp_enter())
5029fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (SMB_LGRP_OFFLINE);
5039fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
504dc20a302Sas 	db = smb_lgrp_db_open(SMB_LGRP_DB_ORD);
505dc20a302Sas 	rc = smb_lgrp_gtbl_lookup(db, SMB_LGRP_GTBL_NAME, &grp,
506dc20a302Sas 	    SMB_LGRP_INFO_CMNT, gname);
507dc20a302Sas 	smb_lgrp_db_close(db);
5089fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_lgrp_exit();
509dc20a302Sas 
510dc20a302Sas 	if (rc == SMB_LGRP_SUCCESS) {
511dc20a302Sas 		*cmnt = grp.sg_cmnt;
512dc20a302Sas 		grp.sg_cmnt = NULL;
513dc20a302Sas 		smb_lgrp_free(&grp);
514dc20a302Sas 	}
515dc20a302Sas 
516dc20a302Sas 	return (rc);
517dc20a302Sas }
518dc20a302Sas 
519dc20a302Sas 
520dc20a302Sas /*
521dc20a302Sas  * smb_lgrp_setpriv
522dc20a302Sas  *
523dc20a302Sas  * Enable/disable the specified privilge for the group
524dc20a302Sas  */
525dc20a302Sas int
smb_lgrp_setpriv(char * gname,uint8_t priv_lid,boolean_t enable)526dc20a302Sas smb_lgrp_setpriv(char *gname, uint8_t priv_lid, boolean_t enable)
527dc20a302Sas {
528dc20a302Sas 	sqlite *db;
529dc20a302Sas 	int rc;
530dc20a302Sas 
531fe1c642dSBill Krier 	if (!smb_lgrp_normalize_name(gname))
532dc20a302Sas 		return (SMB_LGRP_INVALID_NAME);
533dc20a302Sas 
534dc20a302Sas 	if ((priv_lid < SE_MIN_LUID) || (priv_lid > SE_MAX_LUID))
535dc20a302Sas 		return (SMB_LGRP_NO_SUCH_PRIV);
536dc20a302Sas 
5379fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (!smb_lgrp_enter())
5389fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (SMB_LGRP_OFFLINE);
5399fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
540dc20a302Sas 	db = smb_lgrp_db_open(SMB_LGRP_DB_ORW);
541dc20a302Sas 	rc = smb_lgrp_gtbl_update_plist(db, gname, priv_lid, enable);
542dc20a302Sas 	smb_lgrp_db_close(db);
5439fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_lgrp_exit();
544dc20a302Sas 
545dc20a302Sas 	if (enable) {
546dc20a302Sas 		if (rc == SMB_LGRP_PRIV_HELD)
547dc20a302Sas 			rc = SMB_LGRP_SUCCESS;
548dc20a302Sas 	} else {
549dc20a302Sas 		if (rc == SMB_LGRP_PRIV_NOT_HELD)
550dc20a302Sas 			rc = SMB_LGRP_SUCCESS;
551dc20a302Sas 	}
552dc20a302Sas 
553dc20a302Sas 	return (rc);
554dc20a302Sas }
555dc20a302Sas 
556dc20a302Sas /*
557dc20a302Sas  * smb_lgrp_getpriv
558dc20a302Sas  *
559dc20a302Sas  * Obtain the status of the specified privilge for the group
560dc20a302Sas  */
561dc20a302Sas int
smb_lgrp_getpriv(char * gname,uint8_t priv_lid,boolean_t * enable)562dc20a302Sas smb_lgrp_getpriv(char *gname, uint8_t priv_lid, boolean_t *enable)
563dc20a302Sas {
564dc20a302Sas 	sqlite *db;
565dc20a302Sas 	smb_group_t grp;
566dc20a302Sas 	int rc;
567dc20a302Sas 
568fe1c642dSBill Krier 	if (!smb_lgrp_normalize_name(gname))
569dc20a302Sas 		return (SMB_LGRP_INVALID_NAME);
570dc20a302Sas 
571dc20a302Sas 	if ((priv_lid < SE_MIN_LUID) || (priv_lid > SE_MAX_LUID))
572dc20a302Sas 		return (SMB_LGRP_NO_SUCH_PRIV);
573dc20a302Sas 
5749fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (!smb_lgrp_enter())
5759fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (SMB_LGRP_OFFLINE);
5769fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
577dc20a302Sas 	db = smb_lgrp_db_open(SMB_LGRP_DB_ORD);
578dc20a302Sas 	rc = smb_lgrp_gtbl_lookup(db, SMB_LGRP_GTBL_NAME, &grp,
579dc20a302Sas 	    SMB_LGRP_INFO_PRIV, gname);
580dc20a302Sas 	smb_lgrp_db_close(db);
5819fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_lgrp_exit();
582dc20a302Sas 
583dc20a302Sas 	if (rc == SMB_LGRP_SUCCESS) {
584dc20a302Sas 		*enable = (smb_privset_query(grp.sg_privs, priv_lid) == 1);
585dc20a302Sas 		smb_lgrp_free(&grp);
586dc20a302Sas 	}
587dc20a302Sas 
588dc20a302Sas 	return (rc);
589dc20a302Sas }
590dc20a302Sas 
591dc20a302Sas /*
592dc20a302Sas  * smb_lgrp_add_member
593dc20a302Sas  *
594dc20a302Sas  * Add the given account to the specified group as its member.
595dc20a302Sas  */
596dc20a302Sas int
smb_lgrp_add_member(char * gname,smb_sid_t * msid,uint16_t sid_type)5976537f381Sas smb_lgrp_add_member(char *gname, smb_sid_t *msid, uint16_t sid_type)
598dc20a302Sas {
599dc20a302Sas 	sqlite *db;
600dc20a302Sas 	smb_gsid_t mid;
601dc20a302Sas 	int rc;
602dc20a302Sas 
603fe1c642dSBill Krier 	if (!smb_lgrp_normalize_name(gname))
604dc20a302Sas 		return (SMB_LGRP_INVALID_NAME);
605dc20a302Sas 
6066537f381Sas 	if (!smb_sid_isvalid(msid))
607dc20a302Sas 		return (SMB_LGRP_INVALID_ARG);
608dc20a302Sas 
609dc20a302Sas 	if (!smb_lgrp_chkmember(sid_type))
610dc20a302Sas 		return (SMB_LGRP_INVALID_MEMBER);
611dc20a302Sas 
612dc20a302Sas 	mid.gs_sid = msid;
613dc20a302Sas 	mid.gs_type = sid_type;
614dc20a302Sas 
6159fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (!smb_lgrp_enter())
6169fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (SMB_LGRP_OFFLINE);
6179fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
618dc20a302Sas 	db = smb_lgrp_db_open(SMB_LGRP_DB_ORW);
619dc20a302Sas 	rc = smb_lgrp_gtbl_update_mlist(db, gname, &mid, SMB_LGRP_DB_ADDMEMBER);
620dc20a302Sas 	smb_lgrp_db_close(db);
621dc20a302Sas 
6229fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_lgrp_exit();
623dc20a302Sas 	return (rc);
624dc20a302Sas }
625dc20a302Sas 
626dc20a302Sas /*
627dc20a302Sas  * smb_lgrp_del_member
628dc20a302Sas  *
629dc20a302Sas  * Delete the specified member from the given group.
630dc20a302Sas  */
631dc20a302Sas int
smb_lgrp_del_member(char * gname,smb_sid_t * msid,uint16_t sid_type)6326537f381Sas smb_lgrp_del_member(char *gname, smb_sid_t *msid, uint16_t sid_type)
633dc20a302Sas {
634dc20a302Sas 	sqlite *db;
635dc20a302Sas 	smb_gsid_t mid;
636dc20a302Sas 	int rc;
637dc20a302Sas 
638fe1c642dSBill Krier 	if (!smb_lgrp_normalize_name(gname))
639dc20a302Sas 		return (SMB_LGRP_INVALID_NAME);
640dc20a302Sas 
6416537f381Sas 	if (!smb_sid_isvalid(msid))
642dc20a302Sas 		return (SMB_LGRP_INVALID_ARG);
643dc20a302Sas 
644dc20a302Sas 	mid.gs_sid = msid;
645dc20a302Sas 	mid.gs_type = sid_type;
646dc20a302Sas 
6479fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (!smb_lgrp_enter())
6489fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (SMB_LGRP_OFFLINE);
6499fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
650dc20a302Sas 	db = smb_lgrp_db_open(SMB_LGRP_DB_ORW);
651dc20a302Sas 	rc = smb_lgrp_gtbl_update_mlist(db, gname, &mid, SMB_LGRP_DB_DELMEMBER);
652dc20a302Sas 	smb_lgrp_db_close(db);
653dc20a302Sas 
6549fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_lgrp_exit();
655dc20a302Sas 	return (rc);
656dc20a302Sas }
657dc20a302Sas 
658dc20a302Sas /*
659dc20a302Sas  * smb_lgrp_getbyname
660dc20a302Sas  *
661dc20a302Sas  * Retrieves the information of the group specified by
662dc20a302Sas  * the given name.
663dc20a302Sas  *
664dc20a302Sas  * Note that this function doesn't allocate the group
665dc20a302Sas  * structure itself only the fields, so the given grp
666dc20a302Sas  * pointer has to point to a group structure.
667dc20a302Sas  * Caller must free the allocated memories for the fields
668dc20a302Sas  * by calling smb_lgrp_free().
669dc20a302Sas  */
670dc20a302Sas int
smb_lgrp_getbyname(char * gname,smb_group_t * grp)671dc20a302Sas smb_lgrp_getbyname(char *gname, smb_group_t *grp)
672dc20a302Sas {
673dc20a302Sas 	sqlite *db;
674dc20a302Sas 	int rc;
675dc20a302Sas 
676fe1c642dSBill Krier 	if (!smb_lgrp_normalize_name(gname))
677dc20a302Sas 		return (SMB_LGRP_INVALID_NAME);
678dc20a302Sas 
6799fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (!smb_lgrp_enter())
6809fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (SMB_LGRP_OFFLINE);
6819fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
682dc20a302Sas 	db = smb_lgrp_db_open(SMB_LGRP_DB_ORD);
683dc20a302Sas 	rc = smb_lgrp_gtbl_lookup(db, SMB_LGRP_GTBL_NAME, grp,
684dc20a302Sas 	    SMB_LGRP_INFO_ALL, gname);
685dc20a302Sas 	smb_lgrp_db_close(db);
686dc20a302Sas 
6879fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_lgrp_exit();
688dc20a302Sas 	return (rc);
689dc20a302Sas }
690dc20a302Sas 
691dc20a302Sas /*
692dc20a302Sas  * smb_lgrp_getbyrid
693dc20a302Sas  *
694dc20a302Sas  * Retrieves the information of the group specified by
695dc20a302Sas  * the given RID and domain type.
696dc20a302Sas  *
697dc20a302Sas  * Note that this function doesn't allocate the group
698dc20a302Sas  * structure itself only the fields, so the given grp
699dc20a302Sas  * pointer has to point to a group structure.
700dc20a302Sas  * Caller must free the allocated memories for the fields
701dc20a302Sas  * by calling smb_lgrp_free().
702dc20a302Sas  *
703dc20a302Sas  * If grp is NULL no information would be returned. The
704dc20a302Sas  * return value of SMB_LGRP_SUCCESS will indicate that a
705dc20a302Sas  * group with the given information exists.
706dc20a302Sas  */
707dc20a302Sas int
smb_lgrp_getbyrid(uint32_t rid,smb_domain_type_t domtype,smb_group_t * grp)7089fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_lgrp_getbyrid(uint32_t rid, smb_domain_type_t domtype, smb_group_t *grp)
709dc20a302Sas {
710dc20a302Sas 	smb_group_t tmpgrp;
711dc20a302Sas 	sqlite *db;
712dc20a302Sas 	int infolvl = SMB_LGRP_INFO_ALL;
713dc20a302Sas 	int rc;
714dc20a302Sas 
7159fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (!smb_lgrp_enter())
7169fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (SMB_LGRP_OFFLINE);
7179fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
718dc20a302Sas 	if (grp == NULL) {
719dc20a302Sas 		grp = &tmpgrp;
720dc20a302Sas 		infolvl = SMB_LGRP_INFO_NONE;
721dc20a302Sas 	}
722dc20a302Sas 
723dc20a302Sas 	db = smb_lgrp_db_open(SMB_LGRP_DB_ORD);
724dc20a302Sas 	rc = smb_lgrp_gtbl_lookup(db, SMB_LGRP_GTBL_SIDRID, grp, infolvl,
725dc20a302Sas 	    rid, domtype);
726dc20a302Sas 	smb_lgrp_db_close(db);
727dc20a302Sas 
7289fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_lgrp_exit();
729dc20a302Sas 	return (rc);
730dc20a302Sas }
731dc20a302Sas 
732dc20a302Sas /*
733dc20a302Sas  * smb_lgrp_numbydomain
734dc20a302Sas  *
735dc20a302Sas  * Returns the number of groups in the given domain in the
736dc20a302Sas  * arg 'count'
737dc20a302Sas  */
738dc20a302Sas int
smb_lgrp_numbydomain(smb_domain_type_t dom_type,int * count)7399fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_lgrp_numbydomain(smb_domain_type_t dom_type, int *count)
740dc20a302Sas {
741dc20a302Sas 	sqlite *db;
742dc20a302Sas 	int dom_idx;
743dc20a302Sas 	int rc;
744dc20a302Sas 
745dc20a302Sas 	switch (dom_type) {
7469fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	case SMB_DOMAIN_LOCAL:
747dc20a302Sas 		dom_idx = SMB_LGRP_LOCAL_IDX;
748dc20a302Sas 		break;
7499fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	case SMB_DOMAIN_BUILTIN:
750dc20a302Sas 		dom_idx = SMB_LGRP_BUILTIN_IDX;
751dc20a302Sas 		break;
752dc20a302Sas 	default:
753dc20a302Sas 		*count = 0;
754dc20a302Sas 		return (SMB_LGRP_INVALID_ARG);
755dc20a302Sas 	}
756dc20a302Sas 
7579fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (!smb_lgrp_enter())
7589fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (SMB_LGRP_OFFLINE);
7599fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
760dc20a302Sas 	db = smb_lgrp_db_open(SMB_LGRP_DB_ORD);
761dc20a302Sas 	rc = smb_lgrp_gtbl_count(db, dom_idx, count);
762dc20a302Sas 	smb_lgrp_db_close(db);
763dc20a302Sas 
7649fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_lgrp_exit();
765dc20a302Sas 	return (rc);
766dc20a302Sas }
767dc20a302Sas 
768dc20a302Sas /*
769dc20a302Sas  * smb_lgrp_free
770dc20a302Sas  *
771dc20a302Sas  * Frees the allocated memory for the fields of the given
772dc20a302Sas  * group structure. Note that this function doesn't free
773dc20a302Sas  * the group itself.
774dc20a302Sas  */
775dc20a302Sas void
smb_lgrp_free(smb_group_t * grp)776dc20a302Sas smb_lgrp_free(smb_group_t *grp)
777dc20a302Sas {
778dc20a302Sas 	int i;
779dc20a302Sas 
780dc20a302Sas 	if (grp == NULL)
781dc20a302Sas 		return;
782dc20a302Sas 
783dc20a302Sas 	free(grp->sg_name);
784dc20a302Sas 	free(grp->sg_cmnt);
7856537f381Sas 	smb_sid_free(grp->sg_id.gs_sid);
786dc20a302Sas 	smb_privset_free(grp->sg_privs);
787dc20a302Sas 
788dc20a302Sas 	for (i = 0; i < grp->sg_nmembers; i++)
7896537f381Sas 		smb_sid_free(grp->sg_members[i].gs_sid);
790dc20a302Sas 	free(grp->sg_members);
791dc20a302Sas }
792dc20a302Sas 
793dc20a302Sas /*
794dc20a302Sas  * smb_lgrp_iteropen
795dc20a302Sas  *
796dc20a302Sas  * Initializes the given group iterator by opening
797dc20a302Sas  * the group database and creating a virtual machine
798dc20a302Sas  * for iteration.
799dc20a302Sas  */
800dc20a302Sas int
smb_lgrp_iteropen(smb_giter_t * iter)801dc20a302Sas smb_lgrp_iteropen(smb_giter_t *iter)
802dc20a302Sas {
803dc20a302Sas 	char *sql;
804dc20a302Sas 	char *errmsg = NULL;
805dc20a302Sas 	int rc = SMB_LGRP_SUCCESS;
806dc20a302Sas 
807dc20a302Sas 	assert(iter);
808dc20a302Sas 
8099fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (!smb_lgrp_enter())
8109fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (SMB_LGRP_OFFLINE);
8119fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
812dc20a302Sas 	bzero(iter, sizeof (smb_giter_t));
813dc20a302Sas 
814dc20a302Sas 	sql = sqlite_mprintf("SELECT * FROM groups");
8159fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (sql == NULL) {
8169fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		smb_lgrp_exit();
817dc20a302Sas 		return (SMB_LGRP_NO_MEMORY);
8189fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
819dc20a302Sas 
820dc20a302Sas 	iter->sgi_db = smb_lgrp_db_open(SMB_LGRP_DB_ORD);
821dc20a302Sas 	if (iter->sgi_db == NULL) {
822dc20a302Sas 		sqlite_freemem(sql);
8239fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		smb_lgrp_exit();
824dc20a302Sas 		return (SMB_LGRP_DBOPEN_FAILED);
825dc20a302Sas 	}
826dc20a302Sas 
827dc20a302Sas 	rc = sqlite_compile(iter->sgi_db, sql, NULL, &iter->sgi_vm, &errmsg);
828dc20a302Sas 	sqlite_freemem(sql);
829dc20a302Sas 
830dc20a302Sas 	if (rc != SQLITE_OK) {
831dc20a302Sas 		syslog(LOG_DEBUG, "failed to create a VM (%s)",
832dc20a302Sas 		    NULL_MSGCHK(errmsg));
833dc20a302Sas 		rc = SMB_LGRP_DB_ERROR;
834dc20a302Sas 	}
835dc20a302Sas 
8369fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_lgrp_exit();
837dc20a302Sas 	return (rc);
838dc20a302Sas }
839dc20a302Sas 
840dc20a302Sas /*
841dc20a302Sas  * smb_lgrp_iterclose
842dc20a302Sas  *
843dc20a302Sas  * Closes the given group iterator.
844dc20a302Sas  */
845dc20a302Sas void
smb_lgrp_iterclose(smb_giter_t * iter)846dc20a302Sas smb_lgrp_iterclose(smb_giter_t *iter)
847dc20a302Sas {
848dc20a302Sas 	char *errmsg = NULL;
849dc20a302Sas 	int rc;
850dc20a302Sas 
851dc20a302Sas 	assert(iter);
852dc20a302Sas 
8539fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (!smb_lgrp_enter())
8549fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return;
8559fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
856dc20a302Sas 	rc = sqlite_finalize(iter->sgi_vm, &errmsg);
857dc20a302Sas 	if (rc != SQLITE_OK) {
858dc20a302Sas 		syslog(LOG_DEBUG, "failed to destroy a VM (%s)",
859dc20a302Sas 		    NULL_MSGCHK(errmsg));
860dc20a302Sas 	}
861dc20a302Sas 
862dc20a302Sas 	smb_lgrp_db_close(iter->sgi_db);
8639fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_lgrp_exit();
8649fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
8659fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
8669fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
8679fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Returns B_TRUE if there has been an error during
8689fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * iteration.
8699fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  */
8709fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States boolean_t
smb_lgrp_itererror(smb_giter_t * iter)8719fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_lgrp_itererror(smb_giter_t *iter)
8729fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
8739fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (iter->sgi_nerr != 0);
874dc20a302Sas }
875dc20a302Sas 
876dc20a302Sas /*
877dc20a302Sas  * smb_lgrp_iterate
878dc20a302Sas  *
879dc20a302Sas  * Iterate through group database
880dc20a302Sas  * Group information is returned in provided group structure.
881dc20a302Sas  *
882dc20a302Sas  * Note that this function doesn't allocate the group
883dc20a302Sas  * structure itself only the fields, so the given grp
884dc20a302Sas  * pointer has to point to a group structure.
885dc20a302Sas  * Caller must free the allocated memories for the fields
886dc20a302Sas  * by calling smb_lgrp_free().
887dc20a302Sas  */
888dc20a302Sas int
smb_lgrp_iterate(smb_giter_t * iter,smb_group_t * grp)889dc20a302Sas smb_lgrp_iterate(smb_giter_t *iter, smb_group_t *grp)
890dc20a302Sas {
891dc20a302Sas 	const char **values;
892dc20a302Sas 	int ncol;
893dc20a302Sas 	int rc;
894dc20a302Sas 	int i;
895dc20a302Sas 
896dc20a302Sas 	if (iter->sgi_vm == NULL || iter->sgi_db == NULL)
897dc20a302Sas 		return (SMB_LGRP_INVALID_ARG);
898dc20a302Sas 
8999fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (!smb_lgrp_enter())
9009fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (SMB_LGRP_OFFLINE);
901dc20a302Sas 
9029fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	for (;;) {
9039fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		bzero(grp, sizeof (smb_group_t));
9049fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		rc = sqlite_step(iter->sgi_vm, &ncol, &values, NULL);
9059fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		if (rc == SQLITE_DONE) {
9069fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			smb_lgrp_exit();
9079fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			return (SMB_LGRP_NO_MORE);
9089fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		}
909dc20a302Sas 
9109fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		if (rc != SQLITE_ROW) {
9119fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			smb_lgrp_exit();
9129fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			return (SMB_LGRP_DBEXEC_FAILED);
9139fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		}
914dc20a302Sas 
9159fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		if (ncol != SMB_LGRP_GTBL_NCOL) {
9169fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			smb_lgrp_exit();
917dc20a302Sas 			return (SMB_LGRP_DB_ERROR);
9189fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		}
9199fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
9209fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		for (i = 0; i < ncol; i++) {
9219fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			if (values[i] == NULL) {
9229fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 				smb_lgrp_exit();
9239fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 				return (SMB_LGRP_DB_ERROR);
9249fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			}
9259fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		}
9269fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
9279fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		rc = smb_lgrp_decode(grp, (char **)values, SMB_LGRP_INFO_ALL,
9289fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		    iter->sgi_db);
9299fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		if (rc == SMB_LGRP_SUCCESS)
9309fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			break;
9319fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
9329fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		iter->sgi_nerr++;
9339fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		syslog(LOG_ERR, "smb_lgrp_iterate: %s", smb_lgrp_strerror(rc));
934dc20a302Sas 	}
935dc20a302Sas 
9369fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_lgrp_exit();
9379fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (rc);
9389fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
939dc20a302Sas }
940dc20a302Sas 
941dc20a302Sas /*
942dc20a302Sas  * smb_lgrp_is_member
943dc20a302Sas  *
944dc20a302Sas  * Check to see if the specified account is a member of
945dc20a302Sas  * the given group.
946dc20a302Sas  */
947dc20a302Sas boolean_t
smb_lgrp_is_member(smb_group_t * grp,smb_sid_t * sid)9486537f381Sas smb_lgrp_is_member(smb_group_t *grp, smb_sid_t *sid)
949dc20a302Sas {
950dc20a302Sas 	int i;
951dc20a302Sas 
952dc20a302Sas 	if (grp == NULL || grp->sg_members == NULL || sid == NULL)
953dc20a302Sas 		return (B_FALSE);
954dc20a302Sas 
955dc20a302Sas 	for (i = 0; i < grp->sg_nmembers; i++) {
9566537f381Sas 		if (smb_sid_cmp(grp->sg_members[i].gs_sid, sid))
957dc20a302Sas 			return (B_TRUE);
958dc20a302Sas 	}
959dc20a302Sas 
960dc20a302Sas 	return (B_FALSE);
961dc20a302Sas }
962dc20a302Sas 
963dc20a302Sas /*
964dc20a302Sas  * smb_lgrp_strerror
965dc20a302Sas  *
966dc20a302Sas  * Returns a text for the given group error code.
967dc20a302Sas  */
968dc20a302Sas char *
smb_lgrp_strerror(int errnum)9699fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_lgrp_strerror(int errnum)
970dc20a302Sas {
9719fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	int	i;
9729fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	int	nerr = (sizeof (errtab) / sizeof (errtab[0]));
9739fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
9749fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	for (i = 0; i < nerr; ++i) {
9759fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		if (errnum == errtab[i].errnum)
9769fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			return (errtab[i].errmsg);
9779fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
9789fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
9799fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return ("unknown local group error");
980dc20a302Sas }
981dc20a302Sas 
982c5866007SKeyur Desai /*
983c5866007SKeyur Desai  * smb_lgrp_err_to_ntstatus
984c5866007SKeyur Desai  *
985c5866007SKeyur Desai  * This routine maps Local group operation errors to NT Status error codes.
986c5866007SKeyur Desai  */
987c5866007SKeyur Desai uint32_t
smb_lgrp_err_to_ntstatus(uint32_t lgrp_err)988c5866007SKeyur Desai smb_lgrp_err_to_ntstatus(uint32_t lgrp_err)
989c5866007SKeyur Desai {
990c5866007SKeyur Desai 	int i;
991c5866007SKeyur Desai 	static struct err_map {
992c5866007SKeyur Desai 		uint32_t lgrp_err;
993c5866007SKeyur Desai 		uint32_t nt_status;
994c5866007SKeyur Desai 	} err_map[] = {
995c5866007SKeyur Desai 		{ SMB_LGRP_SUCCESS,		NT_STATUS_SUCCESS },
996c5866007SKeyur Desai 		{ SMB_LGRP_INVALID_ARG,		NT_STATUS_INVALID_PARAMETER },
997c5866007SKeyur Desai 		{ SMB_LGRP_INVALID_MEMBER,	NT_STATUS_INVALID_MEMBER },
998c5866007SKeyur Desai 		{ SMB_LGRP_INVALID_NAME,	NT_STATUS_INVALID_PARAMETER },
999c5866007SKeyur Desai 		{ SMB_LGRP_NOT_FOUND,		NT_STATUS_NO_SUCH_ALIAS },
1000c5866007SKeyur Desai 		{ SMB_LGRP_EXISTS,		NT_STATUS_ALIAS_EXISTS },
1001c5866007SKeyur Desai 		{ SMB_LGRP_NO_SID,		NT_STATUS_INVALID_SID },
1002c5866007SKeyur Desai 		{ SMB_LGRP_NO_LOCAL_SID,	NT_STATUS_INVALID_SID },
1003c5866007SKeyur Desai 		{ SMB_LGRP_SID_NOTLOCAL,	NT_STATUS_INVALID_SID },
1004c5866007SKeyur Desai 		{ SMB_LGRP_WKSID,		NT_STATUS_INVALID_SID },
1005c5866007SKeyur Desai 		{ SMB_LGRP_NO_MEMORY,		NT_STATUS_NO_MEMORY },
1006c5866007SKeyur Desai 		{ SMB_LGRP_DB_ERROR,		NT_STATUS_INTERNAL_DB_ERROR },
1007c5866007SKeyur Desai 		{ SMB_LGRP_DBINIT_ERROR,	NT_STATUS_INTERNAL_DB_ERROR },
1008c5866007SKeyur Desai 		{ SMB_LGRP_INTERNAL_ERROR,	NT_STATUS_INTERNAL_ERROR },
1009c5866007SKeyur Desai 		{ SMB_LGRP_MEMBER_IN_GROUP,	NT_STATUS_MEMBER_IN_ALIAS },
1010c5866007SKeyur Desai 		{ SMB_LGRP_MEMBER_NOT_IN_GROUP,	NT_STATUS_MEMBER_NOT_IN_ALIAS },
1011c5866007SKeyur Desai 		{ SMB_LGRP_NO_SUCH_PRIV,	NT_STATUS_NO_SUCH_PRIVILEGE },
1012c5866007SKeyur Desai 		{ SMB_LGRP_NO_SUCH_DOMAIN,	NT_STATUS_NO_SUCH_DOMAIN },
1013c5866007SKeyur Desai 		{ SMB_LGRP_PRIV_HELD,		NT_STATUS_SUCCESS },
1014c5866007SKeyur Desai 		{ SMB_LGRP_PRIV_NOT_HELD,	NT_STATUS_PRIVILEGE_NOT_HELD },
1015c5866007SKeyur Desai 		{ SMB_LGRP_BAD_DATA,		NT_STATUS_DATA_ERROR },
1016148c5f43SAlan Wright 		{ SMB_LGRP_NO_MORE,		NT_STATUS_NO_MORE_ENTRIES },
1017c5866007SKeyur Desai 		{ SMB_LGRP_DBOPEN_FAILED,	NT_STATUS_INTERNAL_DB_ERROR },
1018c5866007SKeyur Desai 		{ SMB_LGRP_DBEXEC_FAILED,	NT_STATUS_INTERNAL_DB_ERROR },
1019c5866007SKeyur Desai 		{ SMB_LGRP_DBINIT_FAILED,	NT_STATUS_INTERNAL_DB_ERROR },
1020c5866007SKeyur Desai 		{ SMB_LGRP_DOMLKP_FAILED,	NT_STATUS_INTERNAL_DB_ERROR },
1021c5866007SKeyur Desai 		{ SMB_LGRP_DOMINS_FAILED,	NT_STATUS_INTERNAL_DB_ERROR },
1022c5866007SKeyur Desai 		{ SMB_LGRP_INSERT_FAILED,	NT_STATUS_INTERNAL_DB_ERROR },
1023c5866007SKeyur Desai 		{ SMB_LGRP_DELETE_FAILED,	NT_STATUS_INTERNAL_DB_ERROR },
1024c5866007SKeyur Desai 		{ SMB_LGRP_UPDATE_FAILED,	NT_STATUS_INTERNAL_DB_ERROR },
1025c5866007SKeyur Desai 		{ SMB_LGRP_LOOKUP_FAILED,	NT_STATUS_INTERNAL_DB_ERROR },
1026c5866007SKeyur Desai 		{ SMB_LGRP_NOT_SUPPORTED,	NT_STATUS_NOT_SUPPORTED },
1027148c5f43SAlan Wright 		{ SMB_LGRP_OFFLINE,		NT_STATUS_INTERNAL_ERROR },
1028148c5f43SAlan Wright 		{ SMB_LGRP_POSIXCREATE_FAILED,	NT_STATUS_UNSUCCESSFUL }
1029c5866007SKeyur Desai 	};
1030c5866007SKeyur Desai 
1031c5866007SKeyur Desai 	for (i = 0; i < sizeof (err_map)/sizeof (err_map[0]); ++i) {
1032c5866007SKeyur Desai 		if (err_map[i].lgrp_err == lgrp_err)
1033c5866007SKeyur Desai 			return (err_map[i].nt_status);
1034c5866007SKeyur Desai 	}
1035c5866007SKeyur Desai 
1036c5866007SKeyur Desai 	return (NT_STATUS_INTERNAL_ERROR);
1037c5866007SKeyur Desai }
1038c5866007SKeyur Desai 
1039dc20a302Sas /*
1040dc20a302Sas  * smb_lgrp_chkmember
1041dc20a302Sas  *
1042dc20a302Sas  * Determines valid account types for being member of
104336a00406SGordon Ross  * a local group.  We really have no business trying to
104436a00406SGordon Ross  * keep track of the "type" of SIDs in a group, so just
104536a00406SGordon Ross  * validate that the SID type is a known enum value.
1046dc20a302Sas  */
1047dc20a302Sas static boolean_t
smb_lgrp_chkmember(uint16_t sid_type)1048dc20a302Sas smb_lgrp_chkmember(uint16_t sid_type)
1049dc20a302Sas {
105036a00406SGordon Ross 	switch (sid_type) {
105136a00406SGordon Ross 	case SidTypeNull:
105236a00406SGordon Ross 	case SidTypeUser:
105336a00406SGordon Ross 	case SidTypeGroup:
105436a00406SGordon Ross 	case SidTypeAlias:
105536a00406SGordon Ross 	case SidTypeWellKnownGroup:
105636a00406SGordon Ross 	case SidTypeDeletedAccount:
105736a00406SGordon Ross 	case SidTypeInvalid:
105836a00406SGordon Ross 	case SidTypeUnknown:
105936a00406SGordon Ross 		return (B_TRUE);
106036a00406SGordon Ross 	}
106136a00406SGordon Ross 	return (B_FALSE);
1062dc20a302Sas }
1063dc20a302Sas 
1064dc20a302Sas /*
1065dc20a302Sas  * smb_lgrp_start
1066dc20a302Sas  *
1067dc20a302Sas  * Initializes the library private global variables.
10689fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Create the database, if it doesn't exist, and add
10699fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * the predefined builtin groups.
1070dc20a302Sas  */
1071dc20a302Sas int
smb_lgrp_start(void)1072dc20a302Sas smb_lgrp_start(void)
1073dc20a302Sas {
10749fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	static char	*builtin[] = {
10759fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		"Administrators",
10769fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		"Backup Operators",
10779fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		"Power Users"
10789fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	};
10799fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_wka_t	*wka;
10809fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	char		*localsid;
10819fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	int		i, rc;
10829fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	int		ngrp = sizeof (builtin) / sizeof (builtin[0]);
10839fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
10849fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	(void) mutex_lock(&smb_localgrp.lg_mutex);
10859fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
10869fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if ((localsid = smb_config_get_localsid()) == NULL) {
10879fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		(void) mutex_unlock(&smb_localgrp.lg_mutex);
1088dc20a302Sas 		return (SMB_LGRP_NO_LOCAL_SID);
1089dc20a302Sas 	}
1090dc20a302Sas 
10919fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_localgrp.lg_machine_sid = smb_sid_fromstr(localsid);
10929fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	free(localsid);
10939fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
10949fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (!smb_sid_isvalid(smb_localgrp.lg_machine_sid)) {
10959fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		free(smb_localgrp.lg_machine_sid);
10969fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		smb_localgrp.lg_machine_sid = NULL;
10979fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		(void) mutex_unlock(&smb_localgrp.lg_mutex);
1098dc20a302Sas 		return (SMB_LGRP_NO_LOCAL_SID);
1099dc20a302Sas 	}
1100dc20a302Sas 
1101dc20a302Sas 	rc = smb_lgrp_db_init();
1102dc20a302Sas 	if (rc != SMB_LGRP_SUCCESS) {
11039fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		free(smb_localgrp.lg_machine_sid);
11049fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		smb_localgrp.lg_machine_sid = NULL;
11059fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		(void) mutex_unlock(&smb_localgrp.lg_mutex);
1106dc20a302Sas 		return (rc);
1107dc20a302Sas 	}
1108dc20a302Sas 
11099fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_localgrp.lg_online = B_TRUE;
11109fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	(void) mutex_unlock(&smb_localgrp.lg_mutex);
11119fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
1112dc20a302Sas 	for (i = 0; i < ngrp; i++) {
1113c28afb19SYuri Pankov 		char	*tname;
1114c28afb19SYuri Pankov 
11159fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		if ((wka = smb_wka_lookup_name(builtin[i])) == NULL)
1116dc20a302Sas 			continue;
11179fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
1118c28afb19SYuri Pankov 		if ((tname = strdup(wka->wka_name)) == NULL)
1119c28afb19SYuri Pankov 			return (SMB_LGRP_NO_MEMORY);
1120c28afb19SYuri Pankov 		if (!smb_lgrp_exists(tname)) {
1121c28afb19SYuri Pankov 			rc = smb_lgrp_add(tname, wka->wka_desc);
112229bd2886SAlan Wright 			if (rc != SMB_LGRP_SUCCESS) {
112329bd2886SAlan Wright 				syslog(LOG_DEBUG, "failed to add %s",
1124c28afb19SYuri Pankov 				    tname);
112529bd2886SAlan Wright 			}
112629bd2886SAlan Wright 		}
1127c28afb19SYuri Pankov 		free(tname);
1128dc20a302Sas 	}
1129dc20a302Sas 
1130dc20a302Sas 	return (SMB_LGRP_SUCCESS);
1131dc20a302Sas }
1132dc20a302Sas 
1133dc20a302Sas /*
1134dc20a302Sas  * smb_lgrp_stop
1135dc20a302Sas  *
1136dc20a302Sas  * Unintialize the library global private variables.
1137dc20a302Sas  */
1138dc20a302Sas void
smb_lgrp_stop(void)1139dc20a302Sas smb_lgrp_stop(void)
1140dc20a302Sas {
11419fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	(void) mutex_lock(&smb_localgrp.lg_mutex);
11429fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (!smb_localgrp.lg_online)
11439fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return;
11449fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
11459fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_localgrp.lg_online = B_FALSE;
11469fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
11479fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	while (smb_localgrp.lg_refcnt > 0)
11489fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		(void) cond_wait(&smb_localgrp.lg_cv, &smb_localgrp.lg_mutex);
11499fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
11509fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	free(smb_localgrp.lg_machine_sid);
11519fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_localgrp.lg_machine_sid = NULL;
11529fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	(void) mutex_unlock(&smb_localgrp.lg_mutex);
11539fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
11549fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
11559fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static boolean_t
smb_lgrp_enter(void)11569fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_lgrp_enter(void)
11579fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
11589fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	boolean_t	status;
11599fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
11609fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	(void) mutex_lock(&smb_localgrp.lg_mutex);
11619fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
11629fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	status = smb_localgrp.lg_online;
11639fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
11649fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (smb_localgrp.lg_online)
11659fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		++smb_localgrp.lg_refcnt;
11669fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
11679fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	(void) mutex_unlock(&smb_localgrp.lg_mutex);
11689fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (status);
11699fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
11709fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
11719fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static void
smb_lgrp_exit(void)11729fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_lgrp_exit(void)
11739fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
11749fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	(void) mutex_lock(&smb_localgrp.lg_mutex);
11759fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	assert(smb_localgrp.lg_refcnt > 0);
11769fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
11779fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if ((--smb_localgrp.lg_refcnt) == 0)
11789fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		(void) cond_signal(&smb_localgrp.lg_cv);
11799fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
11809fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	(void) mutex_unlock(&smb_localgrp.lg_mutex);
1181dc20a302Sas }
1182dc20a302Sas 
1183dc20a302Sas /*
1184dc20a302Sas  * smb_lgrp_db_open
1185dc20a302Sas  *
1186dc20a302Sas  * Opens group database with the given mode.
1187dc20a302Sas  */
1188dc20a302Sas static sqlite *
smb_lgrp_db_open(int mode)1189dc20a302Sas smb_lgrp_db_open(int mode)
1190dc20a302Sas {
1191dc20a302Sas 	sqlite *db;
1192dc20a302Sas 	char *errmsg = NULL;
1193dc20a302Sas 
1194dc20a302Sas 	db = sqlite_open(SMB_LGRP_DB_NAME, mode, &errmsg);
1195dc20a302Sas 	if (db == NULL) {
1196dc20a302Sas 		syslog(LOG_ERR, "failed to open group database (%s)",
1197dc20a302Sas 		    NULL_MSGCHK(errmsg));
1198dc20a302Sas 		sqlite_freemem(errmsg);
1199dc20a302Sas 	}
1200dc20a302Sas 
1201dc20a302Sas 	return (db);
1202dc20a302Sas }
1203dc20a302Sas 
1204dc20a302Sas /*
1205dc20a302Sas  * smb_lgrp_db_close
1206dc20a302Sas  *
1207dc20a302Sas  * Closes the given database handle
1208dc20a302Sas  */
1209dc20a302Sas static void
smb_lgrp_db_close(sqlite * db)1210dc20a302Sas smb_lgrp_db_close(sqlite *db)
1211dc20a302Sas {
1212dc20a302Sas 	if (db) {
1213dc20a302Sas 		sqlite_close(db);
1214dc20a302Sas 	}
1215dc20a302Sas }
1216dc20a302Sas 
1217dc20a302Sas /*
1218dc20a302Sas  * smb_lgrp_db_init
1219dc20a302Sas  *
1220dc20a302Sas  * Creates the group database based on the defined SQL statement.
1221dc20a302Sas  * It also initializes db_info and domain tables.
1222dc20a302Sas  */
1223dc20a302Sas static int
smb_lgrp_db_init(void)1224dc20a302Sas smb_lgrp_db_init(void)
1225dc20a302Sas {
1226dc20a302Sas 	int dbrc = SQLITE_OK;
1227dc20a302Sas 	int rc = SMB_LGRP_SUCCESS;
1228dc20a302Sas 	sqlite *db = NULL;
1229dc20a302Sas 	char *errmsg = NULL;
1230dc20a302Sas 
1231dc20a302Sas 	db = sqlite_open(SMB_LGRP_DB_NAME, 0600, &errmsg);
1232dc20a302Sas 	if (db == NULL) {
1233dc20a302Sas 		syslog(LOG_ERR, "failed to create group database (%s)",
1234dc20a302Sas 		    NULL_MSGCHK(errmsg));
1235dc20a302Sas 		sqlite_freemem(errmsg);
1236dc20a302Sas 		return (SMB_LGRP_DBOPEN_FAILED);
1237dc20a302Sas 	}
1238dc20a302Sas 
1239dc20a302Sas 	sqlite_busy_timeout(db, SMB_LGRP_DB_TIMEOUT);
1240dc20a302Sas 	dbrc = sqlite_exec(db, "BEGIN TRANSACTION;", NULL, NULL, &errmsg);
1241dc20a302Sas 	if (dbrc != SQLITE_OK) {
1242dc20a302Sas 		syslog(LOG_DEBUG, "failed to begin database transaction (%s)",
1243dc20a302Sas 		    NULL_MSGCHK(errmsg));
1244dc20a302Sas 		sqlite_freemem(errmsg);
1245dc20a302Sas 		sqlite_close(db);
1246dc20a302Sas 		return (SMB_LGRP_DBEXEC_FAILED);
1247dc20a302Sas 	}
1248dc20a302Sas 
1249dc20a302Sas 	switch (sqlite_exec(db, SMB_LGRP_DB_SQL, NULL, NULL, &errmsg)) {
1250dc20a302Sas 	case SQLITE_ERROR:
1251dc20a302Sas 		/*
1252dc20a302Sas 		 * This is the normal situation: CREATE probably failed because
1253dc20a302Sas 		 * tables already exist. It may indicate an error in SQL as well
1254dc20a302Sas 		 * but we cannot tell.
1255dc20a302Sas 		 */
1256dc20a302Sas 		sqlite_freemem(errmsg);
1257dc20a302Sas 		dbrc = sqlite_exec(db, "ROLLBACK TRANSACTION", NULL, NULL,
1258dc20a302Sas 		    &errmsg);
1259dc20a302Sas 		rc = SMB_LGRP_SUCCESS;
1260dc20a302Sas 		break;
1261dc20a302Sas 
1262dc20a302Sas 	case SQLITE_OK:
1263dc20a302Sas 		dbrc = sqlite_exec(db, "COMMIT TRANSACTION", NULL, NULL,
1264dc20a302Sas 		    &errmsg);
1265dc20a302Sas 		if (dbrc != SQLITE_OK)
1266dc20a302Sas 			break;
1267dc20a302Sas 		rc = smb_lgrp_dtbl_insert(db, NT_BUILTIN_DOMAIN_SIDSTR,
1268dc20a302Sas 		    NULL);
1269dc20a302Sas 		if (rc == SMB_LGRP_SUCCESS)
1270dc20a302Sas 			rc = smb_lgrp_db_setinfo(db);
1271dc20a302Sas 		if (rc != SMB_LGRP_SUCCESS) {
1272dc20a302Sas 			(void) sqlite_close(db);
1273dc20a302Sas 			(void) unlink(SMB_LGRP_DB_NAME);
1274dc20a302Sas 			return (rc);
1275dc20a302Sas 		}
1276dc20a302Sas 		break;
1277dc20a302Sas 
1278dc20a302Sas 	default:
1279dc20a302Sas 		syslog(LOG_ERR,
1280dc20a302Sas 		    "failed to initialize group database (%s)", errmsg);
1281dc20a302Sas 		sqlite_freemem(errmsg);
1282dc20a302Sas 		dbrc = sqlite_exec(db, "ROLLBACK TRANSACTION", NULL, NULL,
1283dc20a302Sas 		    &errmsg);
1284dc20a302Sas 		rc = SMB_LGRP_DBINIT_FAILED;
1285dc20a302Sas 		break;
1286dc20a302Sas 	}
1287dc20a302Sas 
1288dc20a302Sas 	if (dbrc != SQLITE_OK) {
1289dc20a302Sas 		/* this is bad - database may be left in a locked state */
1290dc20a302Sas 		syslog(LOG_DEBUG, "failed to close a transaction (%s)",
1291dc20a302Sas 		    NULL_MSGCHK(errmsg));
1292dc20a302Sas 		sqlite_freemem(errmsg);
1293dc20a302Sas 	}
1294dc20a302Sas 
1295dc20a302Sas 	(void) sqlite_close(db);
1296dc20a302Sas 	return (rc);
1297dc20a302Sas }
1298dc20a302Sas 
1299dc20a302Sas /*
1300dc20a302Sas  * smb_lgrp_gtbl_lookup
1301dc20a302Sas  *
1302dc20a302Sas  * This is a flexible lookup function for the group database.
1303dc20a302Sas  * The key type can be specified by the 'key' arg and the actual key
1304dc20a302Sas  * values can be passed after the 'infolvl' arg. 'infolvl' arg specifies
1305dc20a302Sas  * what information items for the specified group is needed.
1306dc20a302Sas  *
1307dc20a302Sas  * Note that the function assumes the given key is unique and only
1308dc20a302Sas  * specifies one or 0 group. The keys that are supported now are
1309dc20a302Sas  * the group name and the group SID
1310dc20a302Sas  *
1311dc20a302Sas  * Note that this function doesn't allocate the group
1312dc20a302Sas  * structure itself only the fields, so the given grp
1313dc20a302Sas  * pointer has to point to a group structure.
1314dc20a302Sas  * Caller must free the allocated memories for the fields
1315dc20a302Sas  * by calling smb_lgrp_free().
1316dc20a302Sas  */
1317dc20a302Sas static int
smb_lgrp_gtbl_lookup(sqlite * db,int key,smb_group_t * grp,int infolvl,...)1318dc20a302Sas smb_lgrp_gtbl_lookup(sqlite *db, int key, smb_group_t *grp, int infolvl, ...)
1319dc20a302Sas {
1320dc20a302Sas 	char *errmsg = NULL;
1321dc20a302Sas 	char *sql;
1322dc20a302Sas 	char **result;
1323dc20a302Sas 	int nrow, ncol;
1324dc20a302Sas 	int rc, dom_idx;
1325c8ec8eeaSjose borrego 	smb_group_t grpkey;
1326dc20a302Sas 	va_list ap;
1327dc20a302Sas 
1328dc20a302Sas 	if (db == NULL)
1329dc20a302Sas 		return (SMB_LGRP_DBOPEN_FAILED);
1330dc20a302Sas 
1331dc20a302Sas 	bzero(grp, sizeof (smb_group_t));
1332dc20a302Sas 	va_start(ap, infolvl);
1333dc20a302Sas 
1334dc20a302Sas 	switch (key) {
1335dc20a302Sas 	case SMB_LGRP_GTBL_NAME:
1336c8ec8eeaSjose borrego 		grpkey.sg_name = va_arg(ap, char *);
1337dc20a302Sas 		sql = sqlite_mprintf("SELECT * FROM groups WHERE name = '%s'",
1338c8ec8eeaSjose borrego 		    grpkey.sg_name);
1339dc20a302Sas 		break;
1340dc20a302Sas 
1341dc20a302Sas 	case SMB_LGRP_GTBL_SIDRID:
1342c8ec8eeaSjose borrego 		grpkey.sg_rid = va_arg(ap, uint32_t);
13439fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		grpkey.sg_domain = va_arg(ap, smb_domain_type_t);
13449fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		if (grpkey.sg_domain == SMB_DOMAIN_LOCAL) {
1345c8ec8eeaSjose borrego 			dom_idx = SMB_LGRP_LOCAL_IDX;
1346c8ec8eeaSjose borrego 			/* need to map the given rid to a gid */
1347c8ec8eeaSjose borrego 			rc = smb_lgrp_getgid(grpkey.sg_rid,
1348c8ec8eeaSjose borrego 			    (gid_t *)&grpkey.sg_rid);
1349c8ec8eeaSjose borrego 			if (rc != SMB_LGRP_SUCCESS) {
1350c8ec8eeaSjose borrego 				va_end(ap);
1351c8ec8eeaSjose borrego 				return (rc);
1352c8ec8eeaSjose borrego 			}
1353c8ec8eeaSjose borrego 		} else {
1354c8ec8eeaSjose borrego 			dom_idx = SMB_LGRP_BUILTIN_IDX;
1355c8ec8eeaSjose borrego 		}
1356c8ec8eeaSjose borrego 
1357c8ec8eeaSjose borrego 		sql = sqlite_mprintf("SELECT * FROM groups "
1358dc20a302Sas 		    "WHERE (sid_idx = %d) AND (sid_rid = %u)",
1359c8ec8eeaSjose borrego 		    dom_idx, grpkey.sg_rid);
1360dc20a302Sas 		break;
1361dc20a302Sas 
1362dc20a302Sas 	default:
1363dc20a302Sas 		va_end(ap);
1364dc20a302Sas 		return (SMB_LGRP_INVALID_ARG);
1365dc20a302Sas 	}
1366dc20a302Sas 
1367dc20a302Sas 	va_end(ap);
1368dc20a302Sas 	if (sql == NULL)
1369dc20a302Sas 		return (SMB_LGRP_NO_MEMORY);
1370dc20a302Sas 
1371dc20a302Sas 	rc = sqlite_get_table(db, sql, &result, &nrow, &ncol, &errmsg);
1372dc20a302Sas 	sqlite_freemem(sql);
1373dc20a302Sas 
1374dc20a302Sas 	if (rc != SQLITE_OK) {
1375dc20a302Sas 		syslog(LOG_DEBUG, "failed to lookup (%s)", NULL_MSGCHK(errmsg));
1376dc20a302Sas 		sqlite_freemem(errmsg);
1377dc20a302Sas 		return (SMB_LGRP_LOOKUP_FAILED);
1378dc20a302Sas 	}
1379dc20a302Sas 
1380dc20a302Sas 	if (nrow == 0)  {
1381dc20a302Sas 		/* group not found */
1382dc20a302Sas 		sqlite_free_table(result);
1383dc20a302Sas 		return (SMB_LGRP_NOT_FOUND);
1384dc20a302Sas 	}
1385dc20a302Sas 
1386dc20a302Sas 	if (nrow != 1 || ncol != SMB_LGRP_GTBL_NCOL) {
1387dc20a302Sas 		sqlite_free_table(result);
1388dc20a302Sas 		return (SMB_LGRP_DB_ERROR);
1389dc20a302Sas 	}
1390dc20a302Sas 
1391dc20a302Sas 	rc = smb_lgrp_decode(grp, &result[SMB_LGRP_GTBL_NCOL], infolvl, db);
1392dc20a302Sas 	sqlite_free_table(result);
1393dc20a302Sas 	return (rc);
1394dc20a302Sas }
1395dc20a302Sas 
1396dc20a302Sas /*
1397dc20a302Sas  * smb_lgrp_gtbl_exists
1398dc20a302Sas  *
1399dc20a302Sas  * Checks to see if the given group exists or not.
1400dc20a302Sas  */
1401dc20a302Sas static boolean_t
smb_lgrp_gtbl_exists(sqlite * db,char * gname)1402dc20a302Sas smb_lgrp_gtbl_exists(sqlite *db, char *gname)
1403dc20a302Sas {
1404dc20a302Sas 	char *errmsg = NULL;
1405dc20a302Sas 	char *sql;
1406dc20a302Sas 	char **result;
1407dc20a302Sas 	int nrow, ncol;
1408dc20a302Sas 	int rc;
1409dc20a302Sas 
1410dc20a302Sas 	if (db == NULL)
14114fcce487SToomas Soome 		return (B_FALSE);
1412dc20a302Sas 
1413dc20a302Sas 	sql = sqlite_mprintf("SELECT name FROM groups WHERE name = '%s'",
1414dc20a302Sas 	    gname);
1415dc20a302Sas 	rc = sqlite_get_table(db, sql, &result, &nrow, &ncol, &errmsg);
1416dc20a302Sas 	sqlite_freemem(sql);
1417dc20a302Sas 
1418dc20a302Sas 	if (rc != SQLITE_OK) {
1419dc20a302Sas 		syslog(LOG_DEBUG, "failed to lookup %s (%s)",
1420dc20a302Sas 		    gname, NULL_MSGCHK(errmsg));
1421dc20a302Sas 		sqlite_freemem(errmsg);
1422dc20a302Sas 		return (B_FALSE);
1423dc20a302Sas 	}
1424dc20a302Sas 
1425dc20a302Sas 	sqlite_free_table(result);
1426dc20a302Sas 	return (nrow != 0);
1427dc20a302Sas }
1428dc20a302Sas 
1429dc20a302Sas /*
1430dc20a302Sas  * smb_lgrp_gtbl_count
1431dc20a302Sas  *
1432dc20a302Sas  * Counts the number of groups in the domain specified by
1433dc20a302Sas  * 'dom_idx'
1434dc20a302Sas  */
1435dc20a302Sas static int
smb_lgrp_gtbl_count(sqlite * db,int dom_idx,int * count)1436dc20a302Sas smb_lgrp_gtbl_count(sqlite *db, int dom_idx, int *count)
1437dc20a302Sas {
1438dc20a302Sas 	char *errmsg = NULL;
1439dc20a302Sas 	char *sql;
1440dc20a302Sas 	char **result;
1441dc20a302Sas 	int nrow, ncol;
1442dc20a302Sas 	int rc;
1443dc20a302Sas 
1444dc20a302Sas 	*count = 0;
1445dc20a302Sas 	if (db == NULL)
1446dc20a302Sas 		return (SMB_LGRP_DBOPEN_FAILED);
1447dc20a302Sas 
1448dc20a302Sas 	sql = sqlite_mprintf("SELECT sid_idx FROM groups WHERE sid_idx = %d",
1449dc20a302Sas 	    dom_idx);
1450dc20a302Sas 	rc = sqlite_get_table(db, sql, &result, &nrow, &ncol, &errmsg);
1451dc20a302Sas 	sqlite_freemem(sql);
1452dc20a302Sas 
1453dc20a302Sas 	if (rc != SQLITE_OK) {
1454dc20a302Sas 		syslog(LOG_DEBUG, "failed to count (%s)", NULL_MSGCHK(errmsg));
1455dc20a302Sas 		sqlite_freemem(errmsg);
1456dc20a302Sas 		return (SMB_LGRP_LOOKUP_FAILED);
1457dc20a302Sas 	}
1458dc20a302Sas 
1459dc20a302Sas 	sqlite_free_table(result);
1460faa1795aSjb 	if (ncol > 1)
1461dc20a302Sas 		return (SMB_LGRP_DB_ERROR);
1462dc20a302Sas 
1463dc20a302Sas 	*count = nrow;
1464dc20a302Sas 	return (SMB_LGRP_SUCCESS);
1465dc20a302Sas }
1466dc20a302Sas 
1467dc20a302Sas /*
1468dc20a302Sas  * smb_lgrp_gtbl_insert
1469dc20a302Sas  *
1470dc20a302Sas  * Insert a record for the given group in the group database.
1471dc20a302Sas  *
1472dc20a302Sas  * NOTE: this function assumes that this group has no members
1473dc20a302Sas  * at this time.
1474dc20a302Sas  */
1475dc20a302Sas static int
smb_lgrp_gtbl_insert(sqlite * db,smb_group_t * grp)1476dc20a302Sas smb_lgrp_gtbl_insert(sqlite *db, smb_group_t *grp)
1477dc20a302Sas {
1478dc20a302Sas 	smb_lgpid_t privs[SE_MAX_LUID + 1];
1479dc20a302Sas 	smb_lgplist_t plist;
1480dc20a302Sas 	char *errmsg = NULL;
1481dc20a302Sas 	char *sql;
1482dc20a302Sas 	int dom_idx;
1483dc20a302Sas 	int rc;
1484dc20a302Sas 
1485dc20a302Sas 	if (db == NULL)
1486dc20a302Sas 		return (SMB_LGRP_DBOPEN_FAILED);
1487dc20a302Sas 
14889fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	dom_idx = (grp->sg_domain == SMB_DOMAIN_LOCAL)
1489dc20a302Sas 	    ? SMB_LGRP_LOCAL_IDX : SMB_LGRP_BUILTIN_IDX;
1490dc20a302Sas 
1491dc20a302Sas 	plist.p_cnt = SE_MAX_LUID;
1492dc20a302Sas 	plist.p_ids = privs;
1493dc20a302Sas 	smb_lgrp_encode_privset(grp, &plist);
1494dc20a302Sas 
1495c8ec8eeaSjose borrego 	sql = sqlite_mprintf("INSERT INTO groups "
1496dc20a302Sas 	    "(name, sid_idx, sid_rid, sid_type, sid_attrs, comment, "
1497dc20a302Sas 	    "n_privs, privs, n_members, members) "
1498dc20a302Sas 	    "VALUES('%s', %u, %u, %u, %u, '%q', %u, '%q', %u, '%q')",
1499dc20a302Sas 	    grp->sg_name, dom_idx, grp->sg_rid, grp->sg_id.gs_type,
1500dc20a302Sas 	    grp->sg_attr, (grp->sg_cmnt) ? grp->sg_cmnt : "",
1501dc20a302Sas 	    plist.p_cnt, (char *)plist.p_ids, 0, "");
1502dc20a302Sas 
1503dc20a302Sas 	if (sql == NULL)
1504dc20a302Sas 		return (SMB_LGRP_NO_MEMORY);
1505dc20a302Sas 
1506dc20a302Sas 	rc = sqlite_exec(db, sql, NULL, NULL, &errmsg);
1507dc20a302Sas 	sqlite_freemem(sql);
1508dc20a302Sas 
1509dc20a302Sas 	if (rc != SQLITE_OK) {
1510dc20a302Sas 		syslog(LOG_DEBUG, "failed to insert %s (%s)",
1511dc20a302Sas 		    grp->sg_name, NULL_MSGCHK(errmsg));
1512dc20a302Sas 		sqlite_freemem(errmsg);
1513dc20a302Sas 		rc = SMB_LGRP_INSERT_FAILED;
1514dc20a302Sas 	} else {
1515dc20a302Sas 		rc = SMB_LGRP_SUCCESS;
1516dc20a302Sas 	}
1517dc20a302Sas 
1518dc20a302Sas 	return (rc);
1519dc20a302Sas }
1520dc20a302Sas 
1521dc20a302Sas /*
1522dc20a302Sas  * smb_lgrp_gtbl_delete
1523dc20a302Sas  *
1524dc20a302Sas  * Removes the specified group from the database
1525dc20a302Sas  */
1526dc20a302Sas static int
smb_lgrp_gtbl_delete(sqlite * db,char * gname)1527dc20a302Sas smb_lgrp_gtbl_delete(sqlite *db, char *gname)
1528dc20a302Sas {
1529dc20a302Sas 	char *errmsg = NULL;
1530dc20a302Sas 	char *sql;
1531dc20a302Sas 	int rc;
1532dc20a302Sas 
1533dc20a302Sas 	if (db == NULL)
1534dc20a302Sas 		return (SMB_LGRP_DBOPEN_FAILED);
1535dc20a302Sas 
1536dc20a302Sas 	sql = sqlite_mprintf("DELETE FROM groups WHERE name = '%s'", gname);
1537dc20a302Sas 	if (sql == NULL)
1538dc20a302Sas 		return (SMB_LGRP_NO_MEMORY);
1539dc20a302Sas 
1540dc20a302Sas 	rc = sqlite_exec(db, sql, NULL, NULL, &errmsg);
1541dc20a302Sas 	sqlite_freemem(sql);
1542dc20a302Sas 
1543dc20a302Sas 	if (rc != SQLITE_OK) {
1544dc20a302Sas 		syslog(LOG_DEBUG, "failed to delete %s (%s)",
1545dc20a302Sas 		    gname, NULL_MSGCHK(errmsg));
1546dc20a302Sas 		sqlite_freemem(errmsg);
1547dc20a302Sas 		rc = SMB_LGRP_DELETE_FAILED;
1548dc20a302Sas 	} else {
1549dc20a302Sas 		rc = SMB_LGRP_SUCCESS;
1550dc20a302Sas 	}
1551dc20a302Sas 
1552dc20a302Sas 	return (rc);
1553dc20a302Sas }
1554dc20a302Sas 
1555dc20a302Sas /*
1556dc20a302Sas  * smb_lgrp_gtbl_update
1557dc20a302Sas  *
1558dc20a302Sas  * Updates the specified group information, the supported items
1559dc20a302Sas  * are group name and comment
1560dc20a302Sas  */
1561dc20a302Sas static int
smb_lgrp_gtbl_update(sqlite * db,char * gname,smb_group_t * grp,int col_id)1562dc20a302Sas smb_lgrp_gtbl_update(sqlite *db, char *gname, smb_group_t *grp, int col_id)
1563dc20a302Sas {
1564dc20a302Sas 	char *errmsg = NULL;
1565dc20a302Sas 	char *sql;
1566dc20a302Sas 	int rc;
1567dc20a302Sas 
1568dc20a302Sas 	if (db == NULL)
1569dc20a302Sas 		return (SMB_LGRP_DBOPEN_FAILED);
1570dc20a302Sas 
1571dc20a302Sas 	/* UPDATE doesn't fail if gname doesn't exist */
1572dc20a302Sas 	if (!smb_lgrp_gtbl_exists(db, gname))
1573dc20a302Sas 		return (SMB_LGRP_NOT_FOUND);
1574dc20a302Sas 
1575dc20a302Sas 	switch (col_id) {
1576dc20a302Sas 	case SMB_LGRP_GTBL_NAME:
1577dc20a302Sas 		if (smb_lgrp_gtbl_exists(db, grp->sg_name))
1578dc20a302Sas 			return (SMB_LGRP_EXISTS);
1579dc20a302Sas 		sql = sqlite_mprintf("UPDATE groups SET name = '%s' "
1580dc20a302Sas 		    "WHERE name = '%s'", grp->sg_name, gname);
1581dc20a302Sas 		break;
1582dc20a302Sas 
1583dc20a302Sas 	case SMB_LGRP_GTBL_CMNT:
1584dc20a302Sas 		sql = sqlite_mprintf("UPDATE groups SET comment = '%q' "
1585dc20a302Sas 		"WHERE name = '%s'", grp->sg_cmnt, gname);
1586dc20a302Sas 		break;
1587dc20a302Sas 
1588dc20a302Sas 	default:
1589dc20a302Sas 		return (SMB_LGRP_INVALID_ARG);
1590dc20a302Sas 	}
1591dc20a302Sas 
1592dc20a302Sas 	if (sql == NULL)
1593dc20a302Sas 		return (SMB_LGRP_NO_MEMORY);
1594dc20a302Sas 
1595dc20a302Sas 	rc = sqlite_exec(db, sql, NULL, NULL, &errmsg);
1596dc20a302Sas 	sqlite_freemem(sql);
1597dc20a302Sas 
1598dc20a302Sas 	if (rc != SQLITE_OK) {
1599dc20a302Sas 		syslog(LOG_DEBUG, "failed to update %s (%s)",
1600dc20a302Sas 		    gname, NULL_MSGCHK(errmsg));
1601dc20a302Sas 		sqlite_freemem(errmsg);
1602dc20a302Sas 		rc = SMB_LGRP_UPDATE_FAILED;
1603dc20a302Sas 	} else {
1604dc20a302Sas 		rc = SMB_LGRP_SUCCESS;
1605dc20a302Sas 	}
1606dc20a302Sas 
1607dc20a302Sas 	return (rc);
1608dc20a302Sas }
1609dc20a302Sas 
1610dc20a302Sas /*
1611dc20a302Sas  * smb_lgrp_gtbl_update_mlist
1612dc20a302Sas  *
1613dc20a302Sas  * Adds/removes the specified member from the member list of the
1614dc20a302Sas  * given group
1615dc20a302Sas  */
1616dc20a302Sas static int
smb_lgrp_gtbl_update_mlist(sqlite * db,char * gname,smb_gsid_t * member,int flags)1617dc20a302Sas smb_lgrp_gtbl_update_mlist(sqlite *db, char *gname, smb_gsid_t *member,
1618dc20a302Sas     int flags)
1619dc20a302Sas {
1620dc20a302Sas 	smb_lgmlist_t new_members;
1621dc20a302Sas 	smb_lgmlist_t members;
1622dc20a302Sas 	smb_lgmid_t mid;
1623dc20a302Sas 	char *errmsg = NULL;
1624dc20a302Sas 	char *sql;
1625dc20a302Sas 	char **result;
1626dc20a302Sas 	int nrow, ncol;
1627dc20a302Sas 	int rc;
1628dc20a302Sas 
1629dc20a302Sas 	if (db == NULL)
1630dc20a302Sas 		return (SMB_LGRP_DBOPEN_FAILED);
1631dc20a302Sas 
1632dc20a302Sas 	sql = sqlite_mprintf("SELECT n_members, members FROM groups "
1633dc20a302Sas 	    "WHERE name = '%s'", gname);
1634dc20a302Sas 
1635dc20a302Sas 	if (sql == NULL)
1636dc20a302Sas 		return (SMB_LGRP_NO_MEMORY);
1637dc20a302Sas 
1638dc20a302Sas 	rc = sqlite_get_table(db, sql, &result, &nrow, &ncol, &errmsg);
1639dc20a302Sas 	sqlite_freemem(sql);
1640dc20a302Sas 
1641dc20a302Sas 	if (rc != SQLITE_OK) {
1642dc20a302Sas 		syslog(LOG_DEBUG, "failed to lookup %s (%s)",
1643dc20a302Sas 		    gname, NULL_MSGCHK(errmsg));
1644dc20a302Sas 		sqlite_freemem(errmsg);
1645dc20a302Sas 		return (SMB_LGRP_LOOKUP_FAILED);
1646dc20a302Sas 	}
1647dc20a302Sas 
1648dc20a302Sas 	if (nrow == 0)  {
1649dc20a302Sas 		/* group not found */
1650dc20a302Sas 		sqlite_free_table(result);
1651dc20a302Sas 		return (SMB_LGRP_NOT_FOUND);
1652dc20a302Sas 	}
1653dc20a302Sas 
1654dc20a302Sas 	if (nrow != 1 || ncol != 2) {
1655dc20a302Sas 		sqlite_free_table(result);
1656dc20a302Sas 		return (SMB_LGRP_DB_ERROR);
1657dc20a302Sas 	}
1658dc20a302Sas 
1659dc20a302Sas 	bzero(&mid, sizeof (mid));
1660dc20a302Sas 	mid.m_type = member->gs_type;
1661dc20a302Sas 	rc = smb_lgrp_dtbl_getidx(db, member->gs_sid, mid.m_type,
1662dc20a302Sas 	    &mid.m_idx, &mid.m_rid);
1663dc20a302Sas 	if (rc != SMB_LGRP_SUCCESS) {
1664dc20a302Sas 		sqlite_free_table(result);
1665dc20a302Sas 		return (rc);
1666dc20a302Sas 	}
1667dc20a302Sas 
1668dc20a302Sas 	members.m_cnt = atoi(result[2]);
1669dc20a302Sas 	members.m_ids = result[3];
1670dc20a302Sas 
1671dc20a302Sas 	switch (flags) {
1672dc20a302Sas 	case SMB_LGRP_DB_ADDMEMBER:
1673dc20a302Sas 		rc = smb_lgrp_mlist_add(&members, &mid, &new_members);
1674dc20a302Sas 		break;
1675dc20a302Sas 	case SMB_LGRP_DB_DELMEMBER:
1676dc20a302Sas 		rc = smb_lgrp_mlist_del(&members, &mid, &new_members);
1677dc20a302Sas 		break;
1678dc20a302Sas 	default:
1679dc20a302Sas 		rc = SMB_LGRP_INVALID_ARG;
1680dc20a302Sas 	}
1681dc20a302Sas 
1682dc20a302Sas 	sqlite_free_table(result);
1683dc20a302Sas 	if (rc != SMB_LGRP_SUCCESS)
1684dc20a302Sas 		return (rc);
1685dc20a302Sas 
1686dc20a302Sas 	sql = sqlite_mprintf("UPDATE groups SET n_members = %u, members = '%s'"
1687dc20a302Sas 	    " WHERE name = '%s'", new_members.m_cnt, new_members.m_ids, gname);
1688dc20a302Sas 
1689dc20a302Sas 	free(new_members.m_ids);
1690dc20a302Sas 
1691dc20a302Sas 	if (sql == NULL)
1692dc20a302Sas 		return (SMB_LGRP_NO_MEMORY);
1693dc20a302Sas 
1694dc20a302Sas 	rc = sqlite_exec(db, sql, NULL, NULL, &errmsg);
1695dc20a302Sas 	sqlite_freemem(sql);
1696dc20a302Sas 
1697dc20a302Sas 	if (rc != SQLITE_OK) {
1698dc20a302Sas 		syslog(LOG_DEBUG, "failed to update %s (%s)", gname,
1699dc20a302Sas 		    NULL_MSGCHK(errmsg));
1700dc20a302Sas 		sqlite_freemem(errmsg);
1701dc20a302Sas 		rc = SMB_LGRP_UPDATE_FAILED;
1702dc20a302Sas 	} else {
1703dc20a302Sas 		rc = SMB_LGRP_SUCCESS;
1704dc20a302Sas 	}
1705dc20a302Sas 
1706dc20a302Sas 	return (rc);
1707dc20a302Sas }
1708dc20a302Sas 
1709dc20a302Sas /*
1710dc20a302Sas  * smb_lgrp_gtbl_update_plist
1711dc20a302Sas  *
1712dc20a302Sas  * Adds/removes the specified privilege from the privilege list of the
1713dc20a302Sas  * given group
1714dc20a302Sas  */
1715dc20a302Sas static int
smb_lgrp_gtbl_update_plist(sqlite * db,char * gname,uint8_t priv_id,boolean_t enable)1716dc20a302Sas smb_lgrp_gtbl_update_plist(sqlite *db, char *gname, uint8_t priv_id,
1717dc20a302Sas     boolean_t enable)
1718dc20a302Sas {
1719dc20a302Sas 	char *sql;
1720dc20a302Sas 	char *errmsg = NULL;
1721dc20a302Sas 	char **result;
1722dc20a302Sas 	int nrow, ncol;
1723dc20a302Sas 	int rc;
1724dc20a302Sas 	smb_lgplist_t privs;
1725dc20a302Sas 	smb_lgplist_t new_privs;
1726dc20a302Sas 
1727dc20a302Sas 	if (db == NULL)
1728dc20a302Sas 		return (SMB_LGRP_DBOPEN_FAILED);
1729dc20a302Sas 
1730dc20a302Sas 	sql = sqlite_mprintf("SELECT n_privs, privs FROM groups "
1731dc20a302Sas 	    "WHERE name = '%s'", gname);
1732dc20a302Sas 
1733dc20a302Sas 	if (sql == NULL)
1734dc20a302Sas 		return (SMB_LGRP_NO_MEMORY);
1735dc20a302Sas 
1736dc20a302Sas 	rc = sqlite_get_table(db, sql, &result, &nrow, &ncol, &errmsg);
1737dc20a302Sas 	sqlite_freemem(sql);
1738dc20a302Sas 
1739dc20a302Sas 	if (rc != SQLITE_OK) {
1740dc20a302Sas 		syslog(LOG_DEBUG, "failed to lookup %s (%s)",
1741dc20a302Sas 		    gname, NULL_MSGCHK(errmsg));
1742dc20a302Sas 		sqlite_freemem(errmsg);
1743dc20a302Sas 		return (SMB_LGRP_LOOKUP_FAILED);
1744dc20a302Sas 	}
1745dc20a302Sas 
1746dc20a302Sas 	if (nrow == 0)  {
1747dc20a302Sas 		/* group not found */
1748dc20a302Sas 		sqlite_free_table(result);
1749dc20a302Sas 		return (SMB_LGRP_NOT_FOUND);
1750dc20a302Sas 	}
1751dc20a302Sas 
1752dc20a302Sas 	if (nrow != 1 || ncol != 2) {
1753dc20a302Sas 		sqlite_free_table(result);
1754dc20a302Sas 		return (SMB_LGRP_DB_ERROR);
1755dc20a302Sas 	}
1756dc20a302Sas 
1757dc20a302Sas 	privs.p_cnt = atoi(result[2]);
1758dc20a302Sas 	privs.p_ids = (smb_lgpid_t *)result[3];
1759dc20a302Sas 
1760dc20a302Sas 	if (enable)
1761dc20a302Sas 		rc = smb_lgrp_plist_add(&privs, priv_id, &new_privs);
1762dc20a302Sas 	else
1763dc20a302Sas 		rc = smb_lgrp_plist_del(&privs, priv_id, &new_privs);
1764dc20a302Sas 
1765dc20a302Sas 	sqlite_free_table(result);
1766dc20a302Sas 	if (rc != SMB_LGRP_SUCCESS)
1767dc20a302Sas 		return (rc);
1768dc20a302Sas 
1769dc20a302Sas 	sql = sqlite_mprintf("UPDATE groups SET n_privs = %u, privs = '%q'"
1770dc20a302Sas 	    " WHERE name = '%s'", new_privs.p_cnt, (char *)new_privs.p_ids,
1771dc20a302Sas 	    gname);
1772dc20a302Sas 
1773dc20a302Sas 	free(new_privs.p_ids);
1774dc20a302Sas 
1775dc20a302Sas 	if (sql == NULL)
1776dc20a302Sas 		return (SMB_LGRP_NO_MEMORY);
1777dc20a302Sas 
1778dc20a302Sas 	rc = sqlite_exec(db, sql, NULL, NULL, &errmsg);
1779dc20a302Sas 	sqlite_freemem(sql);
1780dc20a302Sas 
1781dc20a302Sas 	if (rc != SQLITE_OK) {
1782dc20a302Sas 		syslog(LOG_DEBUG, "failed to update %s (%s)",
1783dc20a302Sas 		    gname, NULL_MSGCHK(errmsg));
1784dc20a302Sas 		sqlite_freemem(errmsg);
1785dc20a302Sas 		rc = SMB_LGRP_UPDATE_FAILED;
1786dc20a302Sas 	} else {
1787dc20a302Sas 		rc = SMB_LGRP_SUCCESS;
1788dc20a302Sas 	}
1789dc20a302Sas 
1790dc20a302Sas 	return (rc);
1791dc20a302Sas }
1792dc20a302Sas 
1793dc20a302Sas /*
1794dc20a302Sas  * smb_lgrp_dtbl_insert
1795dc20a302Sas  *
1796dc20a302Sas  * Inserts the specified domain SID in the dmain table.
1797dc20a302Sas  * Upon successful insert the index will be returned in
1798dc20a302Sas  * 'dom_idx' arg.
1799dc20a302Sas  */
1800dc20a302Sas static int
smb_lgrp_dtbl_insert(sqlite * db,char * dom_sid,uint32_t * dom_idx)1801dc20a302Sas smb_lgrp_dtbl_insert(sqlite *db, char *dom_sid, uint32_t *dom_idx)
1802dc20a302Sas {
1803dc20a302Sas 	char *errmsg = NULL;
1804dc20a302Sas 	char *sql;
1805dc20a302Sas 	int rc;
1806dc20a302Sas 
1807dc20a302Sas 	sql = sqlite_mprintf("INSERT INTO domains (dom_sid, dom_cnt)"
1808dc20a302Sas 	    " VALUES('%s', 1);", dom_sid);
1809dc20a302Sas 	if (sql == NULL)
1810dc20a302Sas 		return (SMB_LGRP_NO_MEMORY);
1811dc20a302Sas 
1812dc20a302Sas 	rc = sqlite_exec(db, sql, NULL, NULL, &errmsg);
1813dc20a302Sas 	sqlite_freemem(sql);
1814dc20a302Sas 
1815dc20a302Sas 	if (rc != SQLITE_OK) {
1816dc20a302Sas 		syslog(LOG_DEBUG, "failed to insert domain SID (%s)",
1817dc20a302Sas 		    NULL_MSGCHK(errmsg));
1818dc20a302Sas 		sqlite_freemem(errmsg);
1819dc20a302Sas 		return (SMB_LGRP_DOMINS_FAILED);
1820dc20a302Sas 	}
1821dc20a302Sas 
1822dc20a302Sas 	if (dom_idx)
1823dc20a302Sas 		*dom_idx = sqlite_last_insert_rowid(db);
1824dc20a302Sas 	return (SMB_LGRP_SUCCESS);
1825dc20a302Sas }
1826dc20a302Sas 
1827dc20a302Sas /*
1828dc20a302Sas  * smb_lgrp_dtbl_getidx
1829dc20a302Sas  *
1830dc20a302Sas  * Searches the domain table for the domain SID of the
1831dc20a302Sas  * given member SID. If it finds the domain SID it'll
1832dc20a302Sas  * return the index and the RID, otherwise it'll insert
1833dc20a302Sas  * it in the domain table as a new SID.
1834dc20a302Sas  */
1835dc20a302Sas static int
smb_lgrp_dtbl_getidx(sqlite * db,smb_sid_t * sid,uint16_t sid_type,uint32_t * dom_idx,uint32_t * rid)18366537f381Sas smb_lgrp_dtbl_getidx(sqlite *db, smb_sid_t *sid, uint16_t sid_type,
1837dc20a302Sas     uint32_t *dom_idx, uint32_t *rid)
1838dc20a302Sas {
18396537f381Sas 	char sidstr[SMB_SID_STRSZ];
18406537f381Sas 	smb_sid_t *dom_sid;
1841dc20a302Sas 	char **result;
1842dc20a302Sas 	int nrow, ncol;
1843dc20a302Sas 	char *errmsg = NULL;
1844dc20a302Sas 	char *sql;
1845dc20a302Sas 	int rc;
1846dc20a302Sas 
18479fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (smb_sid_indomain(smb_localgrp.lg_machine_sid, sid)) {
1848dc20a302Sas 		/* This is a local SID */
1849dc20a302Sas 		int id_type = (sid_type == SidTypeUser)
1850dc20a302Sas 		    ? SMB_IDMAP_USER : SMB_IDMAP_GROUP;
1851dc20a302Sas 		*dom_idx = SMB_LGRP_LOCAL_IDX;
1852dc20a302Sas 		if (smb_idmap_getid(sid, rid, &id_type) != IDMAP_SUCCESS)
1853dc20a302Sas 			return (SMB_LGRP_INTERNAL_ERROR);
1854faa1795aSjb 
1855faa1795aSjb 		return (SMB_LGRP_SUCCESS);
1856dc20a302Sas 	}
1857dc20a302Sas 
18587f667e74Sjose borrego 	if ((dom_sid = smb_sid_split(sid, rid)) == NULL)
1859dc20a302Sas 		return (SMB_LGRP_NO_MEMORY);
1860dc20a302Sas 
18616537f381Sas 	smb_sid_tostr(dom_sid, sidstr);
1862dc20a302Sas 	free(dom_sid);
1863dc20a302Sas 
1864dc20a302Sas 	sql = sqlite_mprintf("SELECT dom_idx FROM domains WHERE dom_sid = '%s'",
1865dc20a302Sas 	    sidstr);
1866dc20a302Sas 	if (sql == NULL)
1867dc20a302Sas 		return (SMB_LGRP_NO_MEMORY);
1868dc20a302Sas 
1869dc20a302Sas 	rc = sqlite_get_table(db, sql, &result, &nrow, &ncol, &errmsg);
1870dc20a302Sas 	sqlite_freemem(sql);
1871dc20a302Sas 
1872dc20a302Sas 	if (rc != SQLITE_OK) {
1873dc20a302Sas 		syslog(LOG_DEBUG, "failed to lookup domain SID (%s)",
1874dc20a302Sas 		    NULL_MSGCHK(errmsg));
1875dc20a302Sas 		sqlite_freemem(errmsg);
1876dc20a302Sas 		return (SMB_LGRP_DOMLKP_FAILED);
1877dc20a302Sas 	}
1878dc20a302Sas 
1879dc20a302Sas 	switch (nrow) {
1880dc20a302Sas 	case 0:
1881dc20a302Sas 		/* new domain SID; insert it into the domains table */
1882dc20a302Sas 		sqlite_free_table(result);
1883dc20a302Sas 		return (smb_lgrp_dtbl_insert(db, sidstr, dom_idx));
1884dc20a302Sas 
1885dc20a302Sas 	case 1:
1886dc20a302Sas 		*dom_idx = atoi(result[1]);
1887dc20a302Sas 		sqlite_free_table(result);
1888dc20a302Sas 		return (SMB_LGRP_SUCCESS);
1889dc20a302Sas 	}
1890dc20a302Sas 
1891dc20a302Sas 	sqlite_free_table(result);
1892dc20a302Sas 	return (SMB_LGRP_DB_ERROR);
1893dc20a302Sas }
1894dc20a302Sas 
1895dc20a302Sas /*
1896dc20a302Sas  * smb_lgrp_dtbl_getsid
1897dc20a302Sas  *
1898dc20a302Sas  * Searchs the domain table for the given domain index.
1899dc20a302Sas  * Converts the found domain SID to binary format and
1900dc20a302Sas  * returns it in the 'sid' arg.
1901dc20a302Sas  *
1902dc20a302Sas  * Caller must free the returned SID by calling free().
1903dc20a302Sas  */
1904dc20a302Sas static int
smb_lgrp_dtbl_getsid(sqlite * db,uint32_t dom_idx,smb_sid_t ** sid)19056537f381Sas smb_lgrp_dtbl_getsid(sqlite *db, uint32_t dom_idx, smb_sid_t **sid)
1906dc20a302Sas {
1907dc20a302Sas 	char **result;
1908dc20a302Sas 	int nrow, ncol;
1909dc20a302Sas 	char *errmsg = NULL;
1910dc20a302Sas 	char *sql;
1911dc20a302Sas 	int rc;
1912dc20a302Sas 
1913dc20a302Sas 	sql = sqlite_mprintf("SELECT dom_sid FROM domains WHERE dom_idx = %u",
1914dc20a302Sas 	    dom_idx);
1915dc20a302Sas 	if (sql == NULL)
1916dc20a302Sas 		return (SMB_LGRP_NO_MEMORY);
1917dc20a302Sas 
1918dc20a302Sas 	rc = sqlite_get_table(db, sql, &result, &nrow, &ncol, &errmsg);
1919dc20a302Sas 	sqlite_freemem(sql);
1920dc20a302Sas 
1921dc20a302Sas 	if (rc != SQLITE_OK) {
1922dc20a302Sas 		syslog(LOG_DEBUG, "failed to lookup domain index (%s)",
1923dc20a302Sas 		    NULL_MSGCHK(errmsg));
1924dc20a302Sas 		sqlite_freemem(errmsg);
1925dc20a302Sas 		return (SMB_LGRP_DOMLKP_FAILED);
1926dc20a302Sas 	}
1927dc20a302Sas 
1928dc20a302Sas 	switch (nrow) {
1929dc20a302Sas 	case 0:
1930dc20a302Sas 		rc = SMB_LGRP_NO_SUCH_DOMAIN;
1931dc20a302Sas 		break;
1932dc20a302Sas 
1933dc20a302Sas 	case 1:
19346537f381Sas 		*sid = smb_sid_fromstr(result[1]);
1935dc20a302Sas 		rc = (*sid == NULL)
1936dc20a302Sas 		    ? SMB_LGRP_INTERNAL_ERROR : SMB_LGRP_SUCCESS;
1937dc20a302Sas 		break;
1938dc20a302Sas 
1939dc20a302Sas 	default:
1940dc20a302Sas 		rc = SMB_LGRP_DB_ERROR;
1941dc20a302Sas 		break;
1942dc20a302Sas 	}
1943dc20a302Sas 
1944dc20a302Sas 	sqlite_free_table(result);
1945dc20a302Sas 	return (rc);
1946dc20a302Sas }
1947dc20a302Sas 
1948dc20a302Sas /*
1949dc20a302Sas  * smb_lgrp_db_setinfo
1950dc20a302Sas  *
1951dc20a302Sas  * Initializes the db_info table upon database creation.
1952dc20a302Sas  */
1953dc20a302Sas static int
smb_lgrp_db_setinfo(sqlite * db)1954dc20a302Sas smb_lgrp_db_setinfo(sqlite *db)
1955dc20a302Sas {
1956dc20a302Sas 	char *errmsg = NULL;
1957dc20a302Sas 	char *sql;
1958dc20a302Sas 	int rc;
1959dc20a302Sas 
1960dc20a302Sas 	sql = sqlite_mprintf("INSERT INTO db_info (ver_major, ver_minor,"
1961dc20a302Sas 	    " magic) VALUES (%d, %d, %u)", SMB_LGRP_DB_VERMAJOR,
1962dc20a302Sas 	    SMB_LGRP_DB_VERMINOR, SMB_LGRP_DB_MAGIC);
1963dc20a302Sas 
1964dc20a302Sas 	if (sql == NULL)
1965dc20a302Sas 		return (SMB_LGRP_NO_MEMORY);
1966dc20a302Sas 
1967dc20a302Sas 	rc = sqlite_exec(db, sql, NULL, NULL, &errmsg);
1968dc20a302Sas 	sqlite_freemem(sql);
1969dc20a302Sas 	if (rc != SQLITE_OK) {
1970dc20a302Sas 		syslog(LOG_DEBUG, "failed to insert database information (%s)",
1971dc20a302Sas 		    NULL_MSGCHK(errmsg));
1972dc20a302Sas 		sqlite_freemem(errmsg);
1973dc20a302Sas 		rc = SMB_LGRP_DBINIT_ERROR;
1974dc20a302Sas 	} else {
1975dc20a302Sas 		rc = SMB_LGRP_SUCCESS;
1976dc20a302Sas 	}
1977dc20a302Sas 
1978dc20a302Sas 	return (rc);
1979dc20a302Sas }
1980dc20a302Sas 
1981dc20a302Sas /*
1982dc20a302Sas  * smb_lgrp_mlist_add
1983dc20a302Sas  *
1984dc20a302Sas  * Adds the given member (newm) to the input member list (in_members)
1985dc20a302Sas  * if it's not already there. The result list will be returned in
1986dc20a302Sas  * out_members. The caller must free the allocated memory for
1987dc20a302Sas  * out_members by calling free().
1988dc20a302Sas  *
1989dc20a302Sas  * in_members and out_members are hex strings.
1990dc20a302Sas  */
1991dc20a302Sas static int
smb_lgrp_mlist_add(smb_lgmlist_t * in_members,smb_lgmid_t * newm,smb_lgmlist_t * out_members)1992dc20a302Sas smb_lgrp_mlist_add(smb_lgmlist_t *in_members, smb_lgmid_t *newm,
1993dc20a302Sas     smb_lgmlist_t *out_members)
1994dc20a302Sas {
1995dc20a302Sas 	char mid_hex[SMB_LGRP_MID_HEXSZ];
1996dc20a302Sas 	char *in_list;
1997dc20a302Sas 	char *out_list;
1998dc20a302Sas 	int in_size;
1999dc20a302Sas 	int out_size;
2000dc20a302Sas 	int mid_hexsz;
2001dc20a302Sas 	int i;
2002dc20a302Sas 
2003dc20a302Sas 	out_members->m_cnt = 0;
2004dc20a302Sas 	out_members->m_ids = NULL;
2005dc20a302Sas 
2006dc20a302Sas 	bzero(mid_hex, sizeof (mid_hex));
2007dc20a302Sas 	mid_hexsz = bintohex((const char *)newm, sizeof (smb_lgmid_t),
2008dc20a302Sas 	    mid_hex, sizeof (mid_hex));
2009dc20a302Sas 
2010dc20a302Sas 	/*
2011dc20a302Sas 	 * Check to see if this is already a group member
2012dc20a302Sas 	 */
2013dc20a302Sas 	in_list = in_members->m_ids;
2014dc20a302Sas 	for (i = 0; i < in_members->m_cnt; i++) {
2015dc20a302Sas 		if (strncmp(in_list, mid_hex, mid_hexsz) == 0)
2016dc20a302Sas 			return (SMB_LGRP_MEMBER_IN_GROUP);
2017dc20a302Sas 		in_list += mid_hexsz;
2018dc20a302Sas 	}
2019dc20a302Sas 
2020dc20a302Sas 	in_size = (in_members->m_ids) ? strlen(in_members->m_ids) : 0;
2021dc20a302Sas 	out_size = in_size + sizeof (mid_hex) + 1;
2022dc20a302Sas 	out_list = malloc(out_size);
2023dc20a302Sas 	if (out_list == NULL)
2024dc20a302Sas 		return (SMB_LGRP_NO_MEMORY);
2025dc20a302Sas 
2026dc20a302Sas 	bzero(out_list, out_size);
2027dc20a302Sas 	if (in_members->m_ids)
2028dc20a302Sas 		(void) strlcpy(out_list, in_members->m_ids, out_size);
2029dc20a302Sas 	(void) strcat(out_list, mid_hex);
2030dc20a302Sas 
2031dc20a302Sas 	out_members->m_cnt = in_members->m_cnt + 1;
2032dc20a302Sas 	out_members->m_ids = out_list;
2033dc20a302Sas 
2034dc20a302Sas 	return (SMB_LGRP_SUCCESS);
2035dc20a302Sas }
2036dc20a302Sas 
2037dc20a302Sas /*
2038dc20a302Sas  * smb_lgrp_mlist_del
2039dc20a302Sas  *
2040dc20a302Sas  * Removes the given member (msid) from the input member list
2041dc20a302Sas  * (in_members) if it's already there. The result list will b
2042dc20a302Sas  * returned in out_members. The caller must free the allocated
2043dc20a302Sas  * memory for out_members by calling free().
2044dc20a302Sas  *
2045dc20a302Sas  * in_members and out_members are hex strings.
2046d4c7367eSGordon Ross  *
2047d4c7367eSGordon Ross  * Note that we ignore the SID "type" when matching because
2048d4c7367eSGordon Ross  * we always want to delete when the SID part matches.
2049d4c7367eSGordon Ross  * The "type" part can be fiction.
2050dc20a302Sas  */
2051dc20a302Sas static int
smb_lgrp_mlist_del(smb_lgmlist_t * in_members,smb_lgmid_t * mid,smb_lgmlist_t * out_members)2052dc20a302Sas smb_lgrp_mlist_del(smb_lgmlist_t *in_members, smb_lgmid_t *mid,
2053dc20a302Sas     smb_lgmlist_t *out_members)
2054dc20a302Sas {
2055dc20a302Sas 	char mid_hex[SMB_LGRP_MID_HEXSZ];
2056dc20a302Sas 	char *in_list;
2057dc20a302Sas 	char *out_list;
2058dc20a302Sas 	int in_size;
2059dc20a302Sas 	int out_size;
2060dc20a302Sas 	int mid_hexsz;
2061dc20a302Sas 	int out_cnt;
2062dc20a302Sas 	int i;
2063dc20a302Sas 
2064dc20a302Sas 	out_members->m_cnt = 0;
2065dc20a302Sas 	out_members->m_ids = NULL;
2066dc20a302Sas 
2067dc20a302Sas 	if ((in_members == NULL) || (in_members->m_cnt == 0))
2068dc20a302Sas 		return (SMB_LGRP_MEMBER_NOT_IN_GROUP);
2069dc20a302Sas 
2070dc20a302Sas 	in_size = strlen(in_members->m_ids);
2071dc20a302Sas 	out_size = in_size + sizeof (mid_hex) + 1;
2072dc20a302Sas 	out_list = malloc(out_size);
2073dc20a302Sas 	if (out_list == NULL)
2074dc20a302Sas 		return (SMB_LGRP_NO_MEMORY);
2075dc20a302Sas 
2076dc20a302Sas 	*out_list = '\0';
2077dc20a302Sas 
2078dc20a302Sas 	bzero(mid_hex, sizeof (mid_hex));
2079dc20a302Sas 	mid_hexsz = bintohex((const char *)mid, sizeof (smb_lgmid_t),
2080dc20a302Sas 	    mid_hex, sizeof (mid_hex));
2081dc20a302Sas 
2082dc20a302Sas 	in_list = in_members->m_ids;
2083dc20a302Sas 	for (i = 0, out_cnt = 0; i < in_members->m_cnt; i++) {
2084d4c7367eSGordon Ross 		/* Keep only those NOT matching in IDX,RID */
2085d4c7367eSGordon Ross 		if (strncmp(in_list, mid_hex, SMB_LGRP_IDXRID_LEN)) {
2086dc20a302Sas 			(void) strncat(out_list, in_list, mid_hexsz);
2087dc20a302Sas 			out_cnt++;
2088dc20a302Sas 		}
2089dc20a302Sas 		in_list += mid_hexsz;
2090dc20a302Sas 	}
2091dc20a302Sas 
2092dc20a302Sas 	if (out_cnt == in_members->m_cnt) {
2093dc20a302Sas 		free(out_list);
2094dc20a302Sas 		return (SMB_LGRP_MEMBER_NOT_IN_GROUP);
2095dc20a302Sas 	}
2096dc20a302Sas 
2097dc20a302Sas 	out_members->m_cnt = out_cnt;
2098dc20a302Sas 	out_members->m_ids = out_list;
2099dc20a302Sas 	return (SMB_LGRP_SUCCESS);
2100dc20a302Sas }
2101dc20a302Sas 
2102dc20a302Sas /*
2103dc20a302Sas  * smb_lgrp_plist_add
2104dc20a302Sas  *
2105dc20a302Sas  * Adds the given privilege to the input list (in_privs)
2106dc20a302Sas  * if it's not already there. The result list is returned
2107dc20a302Sas  * in out_privs. The caller must free the allocated memory
2108dc20a302Sas  * for out_privs by calling free().
2109dc20a302Sas  */
2110dc20a302Sas static int
smb_lgrp_plist_add(smb_lgplist_t * in_privs,smb_lgpid_t priv_id,smb_lgplist_t * out_privs)2111dc20a302Sas smb_lgrp_plist_add(smb_lgplist_t *in_privs, smb_lgpid_t priv_id,
2112dc20a302Sas     smb_lgplist_t *out_privs)
2113dc20a302Sas {
2114dc20a302Sas 	int i, size;
2115dc20a302Sas 	smb_lgpid_t *pbuf;
2116dc20a302Sas 
2117dc20a302Sas 	out_privs->p_cnt = 0;
2118dc20a302Sas 	out_privs->p_ids = NULL;
2119dc20a302Sas 
2120dc20a302Sas 	for (i = 0; i < in_privs->p_cnt; i++) {
2121dc20a302Sas 		if (in_privs->p_ids[i] == priv_id)
2122dc20a302Sas 			return (SMB_LGRP_PRIV_HELD);
2123dc20a302Sas 	}
2124dc20a302Sas 
2125dc20a302Sas 	size = (in_privs->p_cnt + 1) * sizeof (smb_lgpid_t) + 1;
2126dc20a302Sas 	pbuf = malloc(size);
2127dc20a302Sas 	if (pbuf == NULL)
2128dc20a302Sas 		return (SMB_LGRP_NO_MEMORY);
2129dc20a302Sas 
2130dc20a302Sas 	bzero(pbuf, size);
2131dc20a302Sas 	bcopy(in_privs->p_ids, pbuf, in_privs->p_cnt * sizeof (smb_lgpid_t));
2132dc20a302Sas 	pbuf[in_privs->p_cnt] = priv_id;
2133dc20a302Sas 
2134dc20a302Sas 	out_privs->p_cnt = in_privs->p_cnt + 1;
2135dc20a302Sas 	out_privs->p_ids = pbuf;
2136dc20a302Sas 
2137dc20a302Sas 	return (SMB_LGRP_SUCCESS);
2138dc20a302Sas }
2139dc20a302Sas 
2140dc20a302Sas /*
2141dc20a302Sas  * smb_lgrp_plist_del
2142dc20a302Sas  *
2143dc20a302Sas  * Removes the given privilege from the input list (in_privs)
2144dc20a302Sas  * if it's already there. The result list is returned
2145dc20a302Sas  * in out_privs. The caller must free the allocated memory
2146dc20a302Sas  * for out_privs by calling free().
2147dc20a302Sas  */
2148dc20a302Sas static int
smb_lgrp_plist_del(smb_lgplist_t * in_privs,smb_lgpid_t priv_id,smb_lgplist_t * out_privs)2149dc20a302Sas smb_lgrp_plist_del(smb_lgplist_t *in_privs, smb_lgpid_t priv_id,
2150dc20a302Sas     smb_lgplist_t *out_privs)
2151dc20a302Sas {
2152dc20a302Sas 	int i, size;
2153dc20a302Sas 
2154dc20a302Sas 	out_privs->p_cnt = 0;
2155dc20a302Sas 	out_privs->p_ids = NULL;
2156dc20a302Sas 
2157dc20a302Sas 	if ((in_privs == NULL) || (in_privs->p_cnt == 0))
2158dc20a302Sas 		return (SMB_LGRP_PRIV_NOT_HELD);
2159dc20a302Sas 
2160dc20a302Sas 	size = (in_privs->p_cnt - 1) * sizeof (smb_lgpid_t) + 1;
2161dc20a302Sas 	out_privs->p_ids = malloc(size);
2162dc20a302Sas 	if (out_privs->p_ids == NULL)
2163dc20a302Sas 		return (SMB_LGRP_NO_MEMORY);
2164dc20a302Sas 
2165dc20a302Sas 	bzero(out_privs->p_ids, size);
2166dc20a302Sas 
2167dc20a302Sas 	for (i = 0; i < in_privs->p_cnt; i++) {
2168dc20a302Sas 		if (in_privs->p_ids[i] != priv_id)
2169dc20a302Sas 			out_privs->p_ids[out_privs->p_cnt++] =
2170dc20a302Sas 			    in_privs->p_ids[i];
2171dc20a302Sas 	}
2172dc20a302Sas 
2173dc20a302Sas 	if (out_privs->p_cnt == in_privs->p_cnt) {
2174dc20a302Sas 		free(out_privs->p_ids);
2175dc20a302Sas 		out_privs->p_cnt = 0;
2176dc20a302Sas 		out_privs->p_ids = NULL;
2177dc20a302Sas 		return (SMB_LGRP_PRIV_NOT_HELD);
2178dc20a302Sas 	}
2179dc20a302Sas 
2180dc20a302Sas 	return (SMB_LGRP_SUCCESS);
2181dc20a302Sas }
2182dc20a302Sas 
2183dc20a302Sas /*
2184dc20a302Sas  * smb_lgrp_encode_privset
2185dc20a302Sas  *
2186dc20a302Sas  * Encodes given privilege set into a buffer to be stored in the group
2187dc20a302Sas  * database. Each entry of the encoded buffer contains the privilege ID
2188dc20a302Sas  * of an enable privilege. The returned buffer is null-terminated.
2189dc20a302Sas  */
2190dc20a302Sas static void
smb_lgrp_encode_privset(smb_group_t * grp,smb_lgplist_t * plist)2191dc20a302Sas smb_lgrp_encode_privset(smb_group_t *grp, smb_lgplist_t *plist)
2192dc20a302Sas {
2193dc20a302Sas 	smb_privset_t *privs;
2194dc20a302Sas 	uint32_t pcnt = plist->p_cnt;
2195dc20a302Sas 	int i;
2196dc20a302Sas 
2197dc20a302Sas 	bzero(plist->p_ids, sizeof (smb_lgpid_t) * plist->p_cnt);
2198dc20a302Sas 	plist->p_cnt = 0;
2199dc20a302Sas 
2200dc20a302Sas 	privs = grp->sg_privs;
2201dc20a302Sas 	if ((privs == NULL) || (privs->priv_cnt == 0))
2202dc20a302Sas 		return;
2203dc20a302Sas 
2204dc20a302Sas 	if (pcnt < privs->priv_cnt) {
2205dc20a302Sas 		assert(0);
2206dc20a302Sas 	}
2207dc20a302Sas 
2208dc20a302Sas 	for (i = 0; i < privs->priv_cnt; i++) {
2209dc20a302Sas 		if (privs->priv[i].attrs == SE_PRIVILEGE_ENABLED) {
2210dc20a302Sas 			plist->p_ids[plist->p_cnt++] =
2211dc20a302Sas 			    (uint8_t)privs->priv[i].luid.lo_part;
2212dc20a302Sas 		}
2213dc20a302Sas 	}
2214dc20a302Sas }
2215dc20a302Sas 
2216dc20a302Sas /*
2217dc20a302Sas  * smb_lgrp_decode_privset
2218dc20a302Sas  *
2219dc20a302Sas  * Decodes the privilege information read from group table
2220dc20a302Sas  * (nprivs, privs) into a binray format specified by the
2221dc20a302Sas  * privilege field of smb_group_t
2222dc20a302Sas  */
2223dc20a302Sas static int
smb_lgrp_decode_privset(smb_group_t * grp,char * nprivs,char * privs)2224dc20a302Sas smb_lgrp_decode_privset(smb_group_t *grp, char *nprivs, char *privs)
2225dc20a302Sas {
2226dc20a302Sas 	smb_lgplist_t plist;
2227dc20a302Sas 	int i;
2228dc20a302Sas 
2229dc20a302Sas 	plist.p_cnt = atoi(nprivs);
2230dc20a302Sas 	if (strlen(privs) != plist.p_cnt)
2231dc20a302Sas 		return (SMB_LGRP_BAD_DATA);
2232dc20a302Sas 
2233dc20a302Sas 	plist.p_ids = (smb_lgpid_t *)privs;
2234dc20a302Sas 	grp->sg_privs = smb_privset_new();
2235dc20a302Sas 	if (grp->sg_privs == NULL)
2236dc20a302Sas 		return (SMB_LGRP_NO_MEMORY);
2237dc20a302Sas 
2238dc20a302Sas 	for (i = 0; i < plist.p_cnt; i++)
2239dc20a302Sas 		smb_privset_enable(grp->sg_privs, plist.p_ids[i]);
2240dc20a302Sas 
2241dc20a302Sas 	return (SMB_LGRP_SUCCESS);
2242dc20a302Sas }
2243dc20a302Sas 
2244dc20a302Sas /*
2245dc20a302Sas  * smb_lgrp_decode_members
2246dc20a302Sas  *
2247dc20a302Sas  * Decodes the members information read from group table
22486537f381Sas  * (nmembers, members) into a binary format specified by the
2249dc20a302Sas  * member fields of smb_group_t
2250dc20a302Sas  */
2251dc20a302Sas static int
smb_lgrp_decode_members(smb_group_t * grp,char * nmembers,char * members,sqlite * db)2252dc20a302Sas smb_lgrp_decode_members(smb_group_t *grp, char *nmembers, char *members,
2253dc20a302Sas     sqlite *db)
2254dc20a302Sas {
22556537f381Sas 	smb_lgmid_t *m_id;
2256dc20a302Sas 	smb_lgmid_t *m_ids;
22576537f381Sas 	smb_gsid_t *m_sid;
22586537f381Sas 	smb_gsid_t *m_sids;
22596537f381Sas 	int m_num;
2260dc20a302Sas 	int mids_size;
2261dc20a302Sas 	int i, rc;
2262dc20a302Sas 
22636537f381Sas 	grp->sg_nmembers = 0;
22646537f381Sas 	grp->sg_members = NULL;
22656537f381Sas 
22666537f381Sas 	m_num = atoi(nmembers);
22676537f381Sas 	mids_size = m_num * sizeof (smb_lgmid_t);
22686537f381Sas 	if ((m_ids = malloc(mids_size)) == NULL)
2269dc20a302Sas 		return (SMB_LGRP_NO_MEMORY);
2270dc20a302Sas 
22719fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	m_sids = calloc(m_num, sizeof (smb_gsid_t));
22726537f381Sas 	if (m_sids == NULL) {
2273dc20a302Sas 		free(m_ids);
2274dc20a302Sas 		return (SMB_LGRP_NO_MEMORY);
2275dc20a302Sas 	}
2276dc20a302Sas 
2277dc20a302Sas 	(void) hextobin(members, strlen(members), (char *)m_ids, mids_size);
2278dc20a302Sas 
22796537f381Sas 	m_id = m_ids;
22806537f381Sas 	m_sid = m_sids;
22816537f381Sas 	for (i = 0; i < m_num; i++, m_id++, m_sid++) {
22826537f381Sas 		rc = smb_lgrp_getsid(m_id->m_idx, &m_id->m_rid, m_id->m_type,
22836537f381Sas 		    db, &m_sid->gs_sid);
22846537f381Sas 
2285dc20a302Sas 		if (rc != SMB_LGRP_SUCCESS) {
2286dc20a302Sas 			free(m_ids);
22876537f381Sas 			for (m_sid = m_sids; m_sid->gs_sid != NULL; m_sid++)
22886537f381Sas 				smb_sid_free(m_sid->gs_sid);
22896537f381Sas 			free(m_sids);
22906537f381Sas 			return (rc);
2291dc20a302Sas 		}
2292dc20a302Sas 
22936537f381Sas 		m_sid->gs_type = m_id->m_type;
2294dc20a302Sas 	}
2295dc20a302Sas 
2296dc20a302Sas 	free(m_ids);
22976537f381Sas 
22986537f381Sas 	grp->sg_nmembers = m_num;
22996537f381Sas 	grp->sg_members = m_sids;
2300dc20a302Sas 	return (SMB_LGRP_SUCCESS);
2301dc20a302Sas }
2302dc20a302Sas 
2303dc20a302Sas /*
2304dc20a302Sas  * smb_lgrp_decode
2305dc20a302Sas  *
2306dc20a302Sas  * Fills out the fields of the given group (grp) based in the
2307dc20a302Sas  * string information read from the group table. infolvl determines
2308dc20a302Sas  * which fields are requested and need to be decoded.
2309dc20a302Sas  *
2310dc20a302Sas  * Allocated memories must be freed by calling smb_lgrp_free()
2311dc20a302Sas  * upon successful return.
2312dc20a302Sas  */
2313dc20a302Sas static int
smb_lgrp_decode(smb_group_t * grp,char ** values,int infolvl,sqlite * db)2314dc20a302Sas smb_lgrp_decode(smb_group_t *grp, char **values, int infolvl, sqlite *db)
2315dc20a302Sas {
2316dc20a302Sas 	uint32_t sid_idx;
2317dc20a302Sas 	int rc;
2318dc20a302Sas 
2319dc20a302Sas 	if (infolvl == SMB_LGRP_INFO_NONE)
2320dc20a302Sas 		return (SMB_LGRP_SUCCESS);
2321dc20a302Sas 
2322dc20a302Sas 	if (infolvl & SMB_LGRP_INFO_NAME) {
2323dc20a302Sas 		grp->sg_name = strdup(values[SMB_LGRP_GTBL_NAME]);
2324dc20a302Sas 		if (grp->sg_name == NULL)
2325dc20a302Sas 			return (SMB_LGRP_NO_MEMORY);
2326dc20a302Sas 	}
2327dc20a302Sas 
2328dc20a302Sas 	if (infolvl & SMB_LGRP_INFO_CMNT) {
2329dc20a302Sas 		grp->sg_cmnt = strdup(values[SMB_LGRP_GTBL_CMNT]);
2330dc20a302Sas 		if (grp->sg_cmnt == NULL) {
2331dc20a302Sas 			smb_lgrp_free(grp);
2332dc20a302Sas 			return (SMB_LGRP_NO_MEMORY);
2333dc20a302Sas 		}
2334dc20a302Sas 	}
2335dc20a302Sas 
2336dc20a302Sas 
2337dc20a302Sas 	if (infolvl & SMB_LGRP_INFO_SID) {
2338dc20a302Sas 		sid_idx = atoi(values[SMB_LGRP_GTBL_SIDIDX]);
2339dc20a302Sas 		grp->sg_rid = atoi(values[SMB_LGRP_GTBL_SIDRID]);
2340dc20a302Sas 		grp->sg_attr = atoi(values[SMB_LGRP_GTBL_SIDATR]);
2341dc20a302Sas 		grp->sg_id.gs_type = atoi(values[SMB_LGRP_GTBL_SIDTYP]);
2342dc20a302Sas 		rc = smb_lgrp_getsid(sid_idx, &grp->sg_rid, grp->sg_id.gs_type,
2343dc20a302Sas 		    db, &grp->sg_id.gs_sid);
2344dc20a302Sas 		if (rc != SMB_LGRP_SUCCESS) {
2345dc20a302Sas 			smb_lgrp_free(grp);
23469fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			return (rc);
2347dc20a302Sas 		}
2348dc20a302Sas 		grp->sg_domain = (sid_idx == SMB_LGRP_LOCAL_IDX)
23499fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		    ? SMB_DOMAIN_LOCAL : SMB_DOMAIN_BUILTIN;
2350dc20a302Sas 	}
2351dc20a302Sas 
2352dc20a302Sas 	if (infolvl & SMB_LGRP_INFO_PRIV) {
2353dc20a302Sas 		rc = smb_lgrp_decode_privset(grp, values[SMB_LGRP_GTBL_NPRIVS],
2354dc20a302Sas 		    values[SMB_LGRP_GTBL_PRIVS]);
2355dc20a302Sas 
2356dc20a302Sas 		if (rc != SMB_LGRP_SUCCESS) {
2357dc20a302Sas 			smb_lgrp_free(grp);
2358dc20a302Sas 			return (rc);
2359dc20a302Sas 		}
2360dc20a302Sas 	}
2361dc20a302Sas 
2362dc20a302Sas 	if (infolvl & SMB_LGRP_INFO_MEMB) {
2363dc20a302Sas 		rc = smb_lgrp_decode_members(grp, values[SMB_LGRP_GTBL_NMEMBS],
2364dc20a302Sas 		    values[SMB_LGRP_GTBL_MEMBS], db);
2365dc20a302Sas 		if (rc != SMB_LGRP_SUCCESS) {
2366dc20a302Sas 			smb_lgrp_free(grp);
2367dc20a302Sas 			return (rc);
2368dc20a302Sas 		}
2369dc20a302Sas 	}
2370dc20a302Sas 
2371dc20a302Sas 	return (SMB_LGRP_SUCCESS);
2372dc20a302Sas }
2373dc20a302Sas 
2374dc20a302Sas /*
2375fe1c642dSBill Krier  * smb_lgrp_normalize_name
2376dc20a302Sas  *
2377fe1c642dSBill Krier  * Trim whitespace, validate the group name and convert it to lowercase.
2378dc20a302Sas  */
2379dc20a302Sas static boolean_t
smb_lgrp_normalize_name(char * name)2380fe1c642dSBill Krier smb_lgrp_normalize_name(char *name)
2381dc20a302Sas {
2382fe1c642dSBill Krier 	(void) trim_whitespace(name);
2383dc20a302Sas 
2384fe1c642dSBill Krier 	if (smb_name_validate_account(name) != ERROR_SUCCESS)
2385dc20a302Sas 		return (B_FALSE);
2386dc20a302Sas 
2387bbf6f00cSJordan Brown 	(void) smb_strlwr(name);
2388dc20a302Sas 	return (B_TRUE);
2389dc20a302Sas }
2390dc20a302Sas 
2391dc20a302Sas /*
2392dc20a302Sas  * smb_lgrp_set_default_privs
2393dc20a302Sas  *
2394dc20a302Sas  * set default privileges for Administrators and Backup Operators
2395dc20a302Sas  */
2396dc20a302Sas static void
smb_lgrp_set_default_privs(smb_group_t * grp)2397dc20a302Sas smb_lgrp_set_default_privs(smb_group_t *grp)
2398dc20a302Sas {
2399bbf6f00cSJordan Brown 	if (smb_strcasecmp(grp->sg_name, "Administrators", 0) == 0) {
2400dc20a302Sas 		smb_privset_enable(grp->sg_privs, SE_TAKE_OWNERSHIP_LUID);
2401*3c1aa884SMatt Barden 		smb_privset_enable(grp->sg_privs, SE_BACKUP_LUID);
2402*3c1aa884SMatt Barden 		smb_privset_enable(grp->sg_privs, SE_RESTORE_LUID);
2403dc20a302Sas 		return;
2404dc20a302Sas 	}
2405dc20a302Sas 
2406bbf6f00cSJordan Brown 	if (smb_strcasecmp(grp->sg_name, "Backup Operators", 0) == 0) {
2407dc20a302Sas 		smb_privset_enable(grp->sg_privs, SE_BACKUP_LUID);
2408dc20a302Sas 		smb_privset_enable(grp->sg_privs, SE_RESTORE_LUID);
2409dc20a302Sas 		return;
2410dc20a302Sas 	}
2411dc20a302Sas }
2412dc20a302Sas 
2413dc20a302Sas /*
2414dc20a302Sas  * smb_lgrp_getsid
2415dc20a302Sas  *
2416dc20a302Sas  * Returns a SID based on the provided information
2417dc20a302Sas  * If dom_idx is 0, it means 'rid' contains a UID/GID and the
2418dc20a302Sas  * returned SID will be a local SID. If dom_idx is not 0 then
2419dc20a302Sas  * the domain SID will be fetched from the domain table.
2420dc20a302Sas  */
2421dc20a302Sas static int
smb_lgrp_getsid(int dom_idx,uint32_t * rid,uint16_t sid_type,sqlite * db,smb_sid_t ** sid)2422dc20a302Sas smb_lgrp_getsid(int dom_idx, uint32_t *rid, uint16_t sid_type,
24236537f381Sas     sqlite *db, smb_sid_t **sid)
2424dc20a302Sas {
24256537f381Sas 	smb_sid_t *dom_sid = NULL;
24266537f381Sas 	smb_sid_t *res_sid = NULL;
24279fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	idmap_stat stat;
2428dc20a302Sas 	int id_type;
2429dc20a302Sas 	int rc;
2430dc20a302Sas 
2431dc20a302Sas 	*sid = NULL;
2432dc20a302Sas 	if (dom_idx == SMB_LGRP_LOCAL_IDX) {
2433dc20a302Sas 		id_type = (sid_type == SidTypeUser)
2434dc20a302Sas 		    ? SMB_IDMAP_USER : SMB_IDMAP_GROUP;
24359fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		stat = smb_idmap_getsid(*rid, id_type, &res_sid);
24369fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		if (stat != IDMAP_SUCCESS) {
24379fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			syslog(LOG_ERR, "smb_lgrp_getsid: "
24389fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			    "failed to get a SID for %s id=%u (%d)",
24399fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			    (id_type == SMB_IDMAP_USER) ? "user" : "group",
24409fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			    *rid, stat);
2441dc20a302Sas 			return (SMB_LGRP_NO_SID);
24429fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		}
2443dc20a302Sas 
2444dc20a302Sas 		/*
2445dc20a302Sas 		 * Make sure the returned SID is local
2446dc20a302Sas 		 */
24479fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		if (!smb_sid_indomain(smb_localgrp.lg_machine_sid, res_sid)) {
24489fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			syslog(LOG_ERR, "smb_lgrp_getsid: "
24499fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			    "local %s (%u) is mapped to a non-local SID",
24509fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			    (id_type == SMB_IDMAP_USER) ? "user" : "group",
24519fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			    *rid);
24526537f381Sas 			smb_sid_free(res_sid);
2453dc20a302Sas 			return (SMB_LGRP_SID_NOTLOCAL);
2454dc20a302Sas 		}
2455dc20a302Sas 
24566537f381Sas 		(void) smb_sid_getrid(res_sid, rid);
2457dc20a302Sas 		*sid = res_sid;
2458dc20a302Sas 		return (SMB_LGRP_SUCCESS);
2459dc20a302Sas 	}
2460dc20a302Sas 
2461dc20a302Sas 	rc = smb_lgrp_dtbl_getsid(db, dom_idx, &dom_sid);
24629fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (rc != SMB_LGRP_SUCCESS) {
24639fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		syslog(LOG_ERR, "smb_lgrp_getsid: %s", smb_lgrp_strerror(rc));
2464dc20a302Sas 		return (SMB_LGRP_DB_ERROR);
24659fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
2466dc20a302Sas 
24676537f381Sas 	res_sid = smb_sid_splice(dom_sid, *rid);
24686537f381Sas 	smb_sid_free(dom_sid);
24699fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (res_sid == NULL) {
24709fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		syslog(LOG_ERR, "smb_lgrp_getsid: %s", smb_lgrp_strerror(rc));
2471dc20a302Sas 		return (SMB_LGRP_NO_MEMORY);
24729fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
2473dc20a302Sas 
2474dc20a302Sas 	*sid = res_sid;
2475dc20a302Sas 	return (SMB_LGRP_SUCCESS);
2476dc20a302Sas }
2477c8ec8eeaSjose borrego 
2478c8ec8eeaSjose borrego /*
2479c8ec8eeaSjose borrego  * smb_lgrp_getgid
2480c8ec8eeaSjose borrego  *
2481c8ec8eeaSjose borrego  * Converts given local RID to a local gid since for user
2482c8ec8eeaSjose borrego  * defined local groups, gid is stored in the table.
2483c8ec8eeaSjose borrego  */
2484c8ec8eeaSjose borrego static int
smb_lgrp_getgid(uint32_t rid,gid_t * gid)2485c8ec8eeaSjose borrego smb_lgrp_getgid(uint32_t rid, gid_t *gid)
2486c8ec8eeaSjose borrego {
2487c8ec8eeaSjose borrego 	smb_sid_t *sid;
2488c8ec8eeaSjose borrego 	int idtype;
2489c8ec8eeaSjose borrego 	int rc;
2490c8ec8eeaSjose borrego 
24919fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if ((sid = smb_sid_splice(smb_localgrp.lg_machine_sid, rid)) == NULL)
2492c8ec8eeaSjose borrego 		return (SMB_LGRP_NO_MEMORY);
2493c8ec8eeaSjose borrego 
2494c8ec8eeaSjose borrego 	idtype = SMB_IDMAP_GROUP;
2495c8ec8eeaSjose borrego 	rc = smb_idmap_getid(sid, gid, &idtype);
2496c8ec8eeaSjose borrego 	smb_sid_free(sid);
2497c8ec8eeaSjose borrego 
2498c8ec8eeaSjose borrego 	return ((rc == IDMAP_SUCCESS) ? SMB_LGRP_SUCCESS : SMB_LGRP_NOT_FOUND);
2499c8ec8eeaSjose borrego }
250029bd2886SAlan Wright 
250129bd2886SAlan Wright /*
250229bd2886SAlan Wright  * smb_lgrp_exists
250329bd2886SAlan Wright  *
250429bd2886SAlan Wright  * Returns B_TRUE if the local group with the given name exists.
250529bd2886SAlan Wright  * Otherwise, returns B_FALSE.
250629bd2886SAlan Wright  */
250729bd2886SAlan Wright static boolean_t
smb_lgrp_exists(char * gname)250829bd2886SAlan Wright smb_lgrp_exists(char *gname)
250929bd2886SAlan Wright {
251029bd2886SAlan Wright 	sqlite *db;
251129bd2886SAlan Wright 	boolean_t rc;
251229bd2886SAlan Wright 
2513fe1c642dSBill Krier 	if (!smb_lgrp_normalize_name(gname))
251429bd2886SAlan Wright 		return (B_FALSE);
251529bd2886SAlan Wright 
251629bd2886SAlan Wright 	db = smb_lgrp_db_open(SMB_LGRP_DB_ORD);
251729bd2886SAlan Wright 	if (db == NULL)
251829bd2886SAlan Wright 		return (B_FALSE);
251929bd2886SAlan Wright 
252029bd2886SAlan Wright 	rc = smb_lgrp_gtbl_exists(db, gname);
252129bd2886SAlan Wright 	smb_lgrp_db_close(db);
252229bd2886SAlan Wright 
252329bd2886SAlan Wright 	return (rc);
252429bd2886SAlan Wright }
2525148c5f43SAlan Wright 
2526148c5f43SAlan Wright /*
2527148c5f43SAlan Wright  * smb_lgrp_pgrp_valid_gname
2528148c5f43SAlan Wright  *
2529148c5f43SAlan Wright  * Validate posix group name string.
2530148c5f43SAlan Wright  */
2531148c5f43SAlan Wright static int
smb_lgrp_pgrp_valid_gname(char * group)2532148c5f43SAlan Wright smb_lgrp_pgrp_valid_gname(char *group)
2533148c5f43SAlan Wright {
2534148c5f43SAlan Wright 	char *ptr = group;
2535148c5f43SAlan Wright 	char c;
2536148c5f43SAlan Wright 	int len = 0;
2537148c5f43SAlan Wright 	int badchar = 0;
2538148c5f43SAlan Wright 
2539148c5f43SAlan Wright 	if (!group || !*group)
2540148c5f43SAlan Wright 		return (SMB_LGRP_PGRP_INVALID);
2541148c5f43SAlan Wright 
25424fcce487SToomas Soome 	for (c = *ptr; c != '\0'; ptr++, c = *ptr) {
2543148c5f43SAlan Wright 		len++;
2544148c5f43SAlan Wright 		if (!isprint(c) || (c == ':') || (c == '\n'))
2545148c5f43SAlan Wright 			return (SMB_LGRP_PGRP_INVALID);
2546148c5f43SAlan Wright 
2547148c5f43SAlan Wright 		if (!(islower(c) || isdigit(c)))
2548148c5f43SAlan Wright 			badchar++;
2549148c5f43SAlan Wright 	}
2550148c5f43SAlan Wright 
2551148c5f43SAlan Wright 	if ((len > SMB_LGRP_PGRP_MAXGLEN - 1) || (badchar != 0))
2552148c5f43SAlan Wright 		return (SMB_LGRP_PGRP_INVALID);
2553148c5f43SAlan Wright 
2554148c5f43SAlan Wright 	if (getgrnam(group) != NULL)
2555148c5f43SAlan Wright 		return (SMB_LGRP_PGRP_NOTUNIQUE);
2556148c5f43SAlan Wright 
2557148c5f43SAlan Wright 	return (SMB_LGRP_PGRP_UNIQUE);
2558148c5f43SAlan Wright }
2559148c5f43SAlan Wright 
2560148c5f43SAlan Wright /*
2561148c5f43SAlan Wright  * smb_lgrp_pgrp_add
2562148c5f43SAlan Wright  *
2563148c5f43SAlan Wright  * Create a posix group with the given name.
2564148c5f43SAlan Wright  * This group will be added to the /etc/group file.
2565148c5f43SAlan Wright  */
2566148c5f43SAlan Wright static int
smb_lgrp_pgrp_add(char * group)2567148c5f43SAlan Wright smb_lgrp_pgrp_add(char *group)
2568148c5f43SAlan Wright {
2569148c5f43SAlan Wright 	FILE *etcgrp;
2570148c5f43SAlan Wright 	FILE *etctmp;
2571a7fe1d5bSAndy Stormont 	int o_mask;
2572148c5f43SAlan Wright 	int newdone = 0;
2573148c5f43SAlan Wright 	struct stat sb;
2574148c5f43SAlan Wright 	char buf[SMB_LGRP_PGRP_GRPBUFSIZ];
2575148c5f43SAlan Wright 	gid_t gid;
2576148c5f43SAlan Wright 	int rc = 0;
2577148c5f43SAlan Wright 
2578148c5f43SAlan Wright 	rc = smb_lgrp_pgrp_valid_gname(group);
2579148c5f43SAlan Wright 	if ((rc == SMB_LGRP_PGRP_INVALID) || (rc == SMB_LGRP_PGRP_NOTUNIQUE))
2580148c5f43SAlan Wright 		return (-1);
2581148c5f43SAlan Wright 
2582a7fe1d5bSAndy Stormont 	if ((findnextgid(SMB_LGRP_PGRP_DEFRID, MAXUID, &gid)) != 0)
2583148c5f43SAlan Wright 		return (-1);
2584148c5f43SAlan Wright 
2585148c5f43SAlan Wright 	if ((etcgrp = fopen(SMB_LGRP_PGRP_GROUP, "r")) == NULL)
2586148c5f43SAlan Wright 		return (-1);
2587148c5f43SAlan Wright 
2588148c5f43SAlan Wright 	if (fstat(fileno(etcgrp), &sb) < 0)
2589148c5f43SAlan Wright 		sb.st_mode = S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH;
2590148c5f43SAlan Wright 
2591148c5f43SAlan Wright 	o_mask = umask(077);
2592148c5f43SAlan Wright 	etctmp = fopen(SMB_LGRP_PGRP_GRPTMP, "w+");
2593148c5f43SAlan Wright 	(void) umask(o_mask);
2594148c5f43SAlan Wright 
2595148c5f43SAlan Wright 	if (etctmp == NULL) {
2596148c5f43SAlan Wright 		(void) fclose(etcgrp);
2597148c5f43SAlan Wright 		return (-1);
2598148c5f43SAlan Wright 	}
2599148c5f43SAlan Wright 
2600148c5f43SAlan Wright 	if (lockf(fileno(etctmp), F_LOCK, 0) != 0) {
2601148c5f43SAlan Wright 		(void) fclose(etcgrp);
2602148c5f43SAlan Wright 		(void) fclose(etctmp);
2603148c5f43SAlan Wright 		(void) unlink(SMB_LGRP_PGRP_GRPTMP);
2604148c5f43SAlan Wright 		return (-1);
2605148c5f43SAlan Wright 	}
2606148c5f43SAlan Wright 
2607148c5f43SAlan Wright 	if (fchmod(fileno(etctmp), sb.st_mode) != 0 ||
2608148c5f43SAlan Wright 	    fchown(fileno(etctmp), sb.st_uid, sb.st_gid) != 0) {
2609148c5f43SAlan Wright 		(void) lockf(fileno(etctmp), F_ULOCK, 0);
2610148c5f43SAlan Wright 		(void) fclose(etcgrp);
2611148c5f43SAlan Wright 		(void) fclose(etctmp);
2612148c5f43SAlan Wright 		(void) unlink(SMB_LGRP_PGRP_GRPTMP);
2613148c5f43SAlan Wright 		return (-1);
2614148c5f43SAlan Wright 	}
2615148c5f43SAlan Wright 
2616148c5f43SAlan Wright 	while (fgets(buf, SMB_LGRP_PGRP_GRPBUFSIZ, etcgrp) != NULL) {
2617148c5f43SAlan Wright 		/* Check for NameService reference */
2618148c5f43SAlan Wright 		if (!newdone && (buf[0] == '+' || buf[0] == '-')) {
2619148c5f43SAlan Wright 			(void) fprintf(etctmp, "%s::%u:\n", group, gid);
2620148c5f43SAlan Wright 			newdone = 1;
2621148c5f43SAlan Wright 		}
2622148c5f43SAlan Wright 
2623148c5f43SAlan Wright 		(void) fputs(buf, etctmp);
2624148c5f43SAlan Wright 	}
2625148c5f43SAlan Wright 	(void) fclose(etcgrp);
2626148c5f43SAlan Wright 
2627148c5f43SAlan Wright 	if (!newdone)
2628148c5f43SAlan Wright 		(void) fprintf(etctmp, "%s::%u:\n", group, gid);
2629148c5f43SAlan Wright 
2630148c5f43SAlan Wright 	if (rename(SMB_LGRP_PGRP_GRPTMP, SMB_LGRP_PGRP_GROUP) < 0) {
2631148c5f43SAlan Wright 		(void) lockf(fileno(etctmp), F_ULOCK, 0);
2632148c5f43SAlan Wright 		(void) fclose(etctmp);
2633148c5f43SAlan Wright 		(void) unlink(SMB_LGRP_PGRP_GRPTMP);
2634148c5f43SAlan Wright 		return (-1);
2635148c5f43SAlan Wright 	}
2636148c5f43SAlan Wright 
2637148c5f43SAlan Wright 	(void) lockf(fileno(etctmp), F_ULOCK, 0);
2638148c5f43SAlan Wright 	(void) fclose(etctmp);
2639148c5f43SAlan Wright 	return (0);
2640148c5f43SAlan Wright }
2641