3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
24 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
25 * Copyright (c) 2013 RackTop Systems.
26 */
27
28 #include <stdlib.h>
29 #include <strings.h>
30 #include <unistd.h>
31 #include <syslog.h>
32 #include <thread.h>
33 #include <synch.h>
34 #include <grp.h>
35 #include <assert.h>
36 #include <libintl.h>
37 #include <smbsrv/libsmb.h>
38 #include <smb_sqlite.h>
39 #include <sys/types.h>
40 #include <sys/stat.h>
41 #include <sys/param.h>
42 #include <libcmdutils.h>
43
44 /*
45 * Local domain SID (aka machine SID) is not stored in the domain table
125 #define SMB_LGRP_PGRP_GRPBUFSIZ 5120
126 #define SMB_LGRP_PGRP_GROUP "/etc/group"
127 #define SMB_LGRP_PGRP_MAXGLEN 9 /* max length of group name */
128 #define SMB_LGRP_PGRP_DEFRID 1000 /* lowest cifs created gid */
129
130 #define SMB_LGRP_PGRP_NOTUNIQUE 0
131 #define SMB_LGRP_PGRP_RESERVED 1
132 #define SMB_LGRP_PGRP_UNIQUE 2
133 #define SMB_LGRP_PGRP_TOOBIG 3
134 #define SMB_LGRP_PGRP_INVALID 4
135
136 #define NULL_MSGCHK(msg) ((msg) ? (msg) : "NULL")
137
138 /* Member ID */
139 typedef struct smb_lgmid {
140 uint32_t m_idx;
141 uint32_t m_rid;
142 uint16_t m_type;
143 } smb_lgmid_t;
144
145 #define SMB_LGRP_MID_HEXSZ 32
146
147 /* Member list */
148 typedef struct smb_lgmlist {
149 uint32_t m_cnt;
150 char *m_ids;
151 } smb_lgmlist_t;
152
153 /* Privilege ID */
154 typedef uint8_t smb_lgpid_t;
155
156 /* Privilege list */
157 typedef struct smb_lgplist {
158 uint32_t p_cnt;
159 smb_lgpid_t *p_ids;
160 } smb_lgplist_t;
161
162 static struct {
163 int errnum;
164 char *errmsg;
165 } errtab[] = {
166 { SMB_LGRP_SUCCESS, "success" },
2022 bzero(out_list, out_size);
2023 if (in_members->m_ids)
2024 (void) strlcpy(out_list, in_members->m_ids, out_size);
2025 (void) strcat(out_list, mid_hex);
2026
2027 out_members->m_cnt = in_members->m_cnt + 1;
2028 out_members->m_ids = out_list;
2029
2030 return (SMB_LGRP_SUCCESS);
2031 }
2032
2033 /*
2034 * smb_lgrp_mlist_del
2035 *
2036 * Removes the given member (msid) from the input member list
2037 * (in_members) if it's already there. The result list will b
2038 * returned in out_members. The caller must free the allocated
2039 * memory for out_members by calling free().
2040 *
2041 * in_members and out_members are hex strings.
2042 */
2043 static int
2044 smb_lgrp_mlist_del(smb_lgmlist_t *in_members, smb_lgmid_t *mid,
2045 smb_lgmlist_t *out_members)
2046 {
2047 char mid_hex[SMB_LGRP_MID_HEXSZ];
2048 char *in_list;
2049 char *out_list;
2050 int in_size;
2051 int out_size;
2052 int mid_hexsz;
2053 int out_cnt;
2054 int i;
2055
2056 out_members->m_cnt = 0;
2057 out_members->m_ids = NULL;
2058
2059 if ((in_members == NULL) || (in_members->m_cnt == 0))
2060 return (SMB_LGRP_MEMBER_NOT_IN_GROUP);
2061
2062 in_size = strlen(in_members->m_ids);
2063 out_size = in_size + sizeof (mid_hex) + 1;
2064 out_list = malloc(out_size);
2065 if (out_list == NULL)
2066 return (SMB_LGRP_NO_MEMORY);
2067
2068 *out_list = '\0';
2069
2070 bzero(mid_hex, sizeof (mid_hex));
2071 mid_hexsz = bintohex((const char *)mid, sizeof (smb_lgmid_t),
2072 mid_hex, sizeof (mid_hex));
2073
2074 in_list = in_members->m_ids;
2075 for (i = 0, out_cnt = 0; i < in_members->m_cnt; i++) {
2076 if (strncmp(in_list, mid_hex, mid_hexsz)) {
2077 (void) strncat(out_list, in_list, mid_hexsz);
2078 out_cnt++;
2079 }
2080 in_list += mid_hexsz;
2081 }
2082
2083 if (out_cnt == in_members->m_cnt) {
2084 free(out_list);
2085 return (SMB_LGRP_MEMBER_NOT_IN_GROUP);
2086 }
2087
2088 out_members->m_cnt = out_cnt;
2089 out_members->m_ids = out_list;
2090 return (SMB_LGRP_SUCCESS);
2091 }
2092
2093 /*
2094 * smb_lgrp_plist_add
2095 *
2096 * Adds the given privilege to the input list (in_privs)
|
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright (c) 2013 RackTop Systems.
25 * Copyright 2016 Nexenta Systems, Inc. All rights reserved.
26 */
27
28 #include <stdlib.h>
29 #include <strings.h>
30 #include <unistd.h>
31 #include <syslog.h>
32 #include <thread.h>
33 #include <synch.h>
34 #include <grp.h>
35 #include <assert.h>
36 #include <libintl.h>
37 #include <smbsrv/libsmb.h>
38 #include <smb_sqlite.h>
39 #include <sys/types.h>
40 #include <sys/stat.h>
41 #include <sys/param.h>
42 #include <libcmdutils.h>
43
44 /*
45 * Local domain SID (aka machine SID) is not stored in the domain table
125 #define SMB_LGRP_PGRP_GRPBUFSIZ 5120
126 #define SMB_LGRP_PGRP_GROUP "/etc/group"
127 #define SMB_LGRP_PGRP_MAXGLEN 9 /* max length of group name */
128 #define SMB_LGRP_PGRP_DEFRID 1000 /* lowest cifs created gid */
129
130 #define SMB_LGRP_PGRP_NOTUNIQUE 0
131 #define SMB_LGRP_PGRP_RESERVED 1
132 #define SMB_LGRP_PGRP_UNIQUE 2
133 #define SMB_LGRP_PGRP_TOOBIG 3
134 #define SMB_LGRP_PGRP_INVALID 4
135
136 #define NULL_MSGCHK(msg) ((msg) ? (msg) : "NULL")
137
138 /* Member ID */
139 typedef struct smb_lgmid {
140 uint32_t m_idx;
141 uint32_t m_rid;
142 uint16_t m_type;
143 } smb_lgmid_t;
144
145 /* Buffer size to hold hex form of the above (>24). */
146 #define SMB_LGRP_MID_HEXSZ 32
147
148 /* Size of idx,rid parts of above, in hex form. */
149 #define SMB_LGRP_IDXRID_LEN 16
150
151 /* Member list */
152 typedef struct smb_lgmlist {
153 uint32_t m_cnt;
154 char *m_ids;
155 } smb_lgmlist_t;
156
157 /* Privilege ID */
158 typedef uint8_t smb_lgpid_t;
159
160 /* Privilege list */
161 typedef struct smb_lgplist {
162 uint32_t p_cnt;
163 smb_lgpid_t *p_ids;
164 } smb_lgplist_t;
165
166 static struct {
167 int errnum;
168 char *errmsg;
169 } errtab[] = {
170 { SMB_LGRP_SUCCESS, "success" },
2026 bzero(out_list, out_size);
2027 if (in_members->m_ids)
2028 (void) strlcpy(out_list, in_members->m_ids, out_size);
2029 (void) strcat(out_list, mid_hex);
2030
2031 out_members->m_cnt = in_members->m_cnt + 1;
2032 out_members->m_ids = out_list;
2033
2034 return (SMB_LGRP_SUCCESS);
2035 }
2036
2037 /*
2038 * smb_lgrp_mlist_del
2039 *
2040 * Removes the given member (msid) from the input member list
2041 * (in_members) if it's already there. The result list will b
2042 * returned in out_members. The caller must free the allocated
2043 * memory for out_members by calling free().
2044 *
2045 * in_members and out_members are hex strings.
2046 *
2047 * Note that we ignore the SID "type" when matching because
2048 * we always want to delete when the SID part matches.
2049 * The "type" part can be fiction.
2050 */
2051 static int
2052 smb_lgrp_mlist_del(smb_lgmlist_t *in_members, smb_lgmid_t *mid,
2053 smb_lgmlist_t *out_members)
2054 {
2055 char mid_hex[SMB_LGRP_MID_HEXSZ];
2056 char *in_list;
2057 char *out_list;
2058 int in_size;
2059 int out_size;
2060 int mid_hexsz;
2061 int out_cnt;
2062 int i;
2063
2064 out_members->m_cnt = 0;
2065 out_members->m_ids = NULL;
2066
2067 if ((in_members == NULL) || (in_members->m_cnt == 0))
2068 return (SMB_LGRP_MEMBER_NOT_IN_GROUP);
2069
2070 in_size = strlen(in_members->m_ids);
2071 out_size = in_size + sizeof (mid_hex) + 1;
2072 out_list = malloc(out_size);
2073 if (out_list == NULL)
2074 return (SMB_LGRP_NO_MEMORY);
2075
2076 *out_list = '\0';
2077
2078 bzero(mid_hex, sizeof (mid_hex));
2079 mid_hexsz = bintohex((const char *)mid, sizeof (smb_lgmid_t),
2080 mid_hex, sizeof (mid_hex));
2081
2082 in_list = in_members->m_ids;
2083 for (i = 0, out_cnt = 0; i < in_members->m_cnt; i++) {
2084 /* Keep only those NOT matching in IDX,RID */
2085 if (strncmp(in_list, mid_hex, SMB_LGRP_IDXRID_LEN)) {
2086 (void) strncat(out_list, in_list, mid_hexsz);
2087 out_cnt++;
2088 }
2089 in_list += mid_hexsz;
2090 }
2091
2092 if (out_cnt == in_members->m_cnt) {
2093 free(out_list);
2094 return (SMB_LGRP_MEMBER_NOT_IN_GROUP);
2095 }
2096
2097 out_members->m_cnt = out_cnt;
2098 out_members->m_ids = out_list;
2099 return (SMB_LGRP_SUCCESS);
2100 }
2101
2102 /*
2103 * smb_lgrp_plist_add
2104 *
2105 * Adds the given privilege to the input list (in_privs)
|