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