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 */
26
27 #include <stdlib.h>
28 #include <strings.h>
29 #include <unistd.h>
30 #include <syslog.h>
31 #include <thread.h>
32 #include <synch.h>
33 #include <grp.h>
34 #include <assert.h>
35 #include <libintl.h>
36 #include <smbsrv/libsmb.h>
37 #include <smb_sqlite.h>
38 #include <sys/types.h>
39 #include <sys/stat.h>
40 #include <sys/param.h>
41
42 /*
43 * Local domain SID (aka machine SID) is not stored in the domain table
44 * therefore the index is 0
45 */
46 #define SMB_LGRP_LOCAL_IDX 0
47 #define SMB_LGRP_BUILTIN_IDX 1
48
49 #define SMB_LGRP_DB_NAME "/var/smb/smbgroup.db"
50 #define SMB_LGRP_DB_TIMEOUT 3000 /* in millisecond */
51 #define SMB_LGRP_DB_VERMAJOR 1
52 #define SMB_LGRP_DB_VERMINOR 0
53 #define SMB_LGRP_DB_MAGIC 0x4C475250 /* LGRP */
54
55 #define SMB_LGRP_DB_ORD 1 /* open read-only */
56 #define SMB_LGRP_DB_ORW 2 /* open read/write */
57
58 #define SMB_LGRP_DB_ADDMEMBER 1
59 #define SMB_LGRP_DB_DELMEMBER 2
60
106 #define SMB_LGRP_GTBL_SIDTYP 3
107 #define SMB_LGRP_GTBL_SIDATR 4
108 #define SMB_LGRP_GTBL_CMNT 5
109 #define SMB_LGRP_GTBL_NPRIVS 6
110 #define SMB_LGRP_GTBL_PRIVS 7
111 #define SMB_LGRP_GTBL_NMEMBS 8
112 #define SMB_LGRP_GTBL_MEMBS 9
113
114 #define SMB_LGRP_INFO_NONE 0x00
115 #define SMB_LGRP_INFO_NAME 0x01
116 #define SMB_LGRP_INFO_CMNT 0x02
117 #define SMB_LGRP_INFO_SID 0x04
118 #define SMB_LGRP_INFO_PRIV 0x08
119 #define SMB_LGRP_INFO_MEMB 0x10
120 #define SMB_LGRP_INFO_ALL 0x1F
121
122 #define SMB_LGRP_PGRP_GRPTMP "/etc/gtmp"
123 #define SMB_LGRP_PGRP_GRPBUFSIZ 5120
124 #define SMB_LGRP_PGRP_GROUP "/etc/group"
125 #define SMB_LGRP_PGRP_MAXGLEN 9 /* max length of group name */
126 #define SMB_LGRP_PGRP_DEFRID 99 /* max reserved id */
127
128 #define SMB_LGRP_PGRP_NOTUNIQUE 0
129 #define SMB_LGRP_PGRP_RESERVED 1
130 #define SMB_LGRP_PGRP_UNIQUE 2
131 #define SMB_LGRP_PGRP_TOOBIG 3
132 #define SMB_LGRP_PGRP_INVALID 4
133
134 #define NULL_MSGCHK(msg) ((msg) ? (msg) : "NULL")
135
136 /* Member ID */
137 typedef struct smb_lgmid {
138 uint32_t m_idx;
139 uint32_t m_rid;
140 uint16_t m_type;
141 } smb_lgmid_t;
142
143 #define SMB_LGRP_MID_HEXSZ 32
144
145 /* Member list */
146 typedef struct smb_lgmlist {
2528
2529 for (c = *ptr; c != NULL; ptr++, c = *ptr) {
2530 len++;
2531 if (!isprint(c) || (c == ':') || (c == '\n'))
2532 return (SMB_LGRP_PGRP_INVALID);
2533
2534 if (!(islower(c) || isdigit(c)))
2535 badchar++;
2536 }
2537
2538 if ((len > SMB_LGRP_PGRP_MAXGLEN - 1) || (badchar != 0))
2539 return (SMB_LGRP_PGRP_INVALID);
2540
2541 if (getgrnam(group) != NULL)
2542 return (SMB_LGRP_PGRP_NOTUNIQUE);
2543
2544 return (SMB_LGRP_PGRP_UNIQUE);
2545 }
2546
2547 /*
2548 * smb_lgrp_pgrp_valid_gid
2549 *
2550 * Check to see that the gid is not a reserved gid
2551 * -- nobody (60001), noaccess (60002) or nogroup (65534)
2552 */
2553 static int
2554 smb_lgrp_pgrp_valid_gid(gid_t gid)
2555 {
2556 return (gid != 60001 && gid != 60002 && gid != 65534);
2557 }
2558
2559 /*
2560 * smb_lgrp_pgrp_findnextgid(void)
2561 *
2562 * This method finds the next valid GID.
2563 * It sorts the used GIDs in decreasing order to return MAXUSED + 1.
2564 * It then adds one to obtain the next valid GID.
2565 * On failure, -1 is returned. On success, a valid GID is returned.
2566 */
2567 static int
2568 smb_lgrp_pgrp_findnextgid(void)
2569 {
2570 FILE *fptr;
2571 gid_t last, next;
2572 int gid;
2573
2574 if ((fptr = popen("exec sh -c "
2575 "\"getent group|cut -f3 -d:|sort -nr|uniq \" 2>/dev/null",
2576 "r")) == NULL)
2577 return (-1);
2578
2579 if (fscanf(fptr, "%u\n", &next) == EOF) {
2580 (void) pclose(fptr);
2581 return (SMB_LGRP_PGRP_DEFRID + 1);
2582 }
2583
2584 last = MAXUID;
2585 gid = -1;
2586 do {
2587 if (!smb_lgrp_pgrp_valid_gid(next))
2588 continue;
2589
2590 if (next <= SMB_LGRP_PGRP_DEFRID) {
2591 if (last != SMB_LGRP_PGRP_DEFRID + 1)
2592 gid = SMB_LGRP_PGRP_DEFRID + 1;
2593 break;
2594 }
2595
2596 if ((gid = next + 1) != last) {
2597 while (!smb_lgrp_pgrp_valid_gid((gid_t)gid))
2598 gid++;
2599 if (gid > 0 && gid < last)
2600 break;
2601 }
2602
2603 gid = -1;
2604 last = next;
2605 } while (fscanf(fptr, "%u\n", &next) != EOF);
2606
2607 (void) pclose(fptr);
2608 return (gid);
2609 }
2610
2611 /*
2612 * smb_lgrp_pgrp_add
2613 *
2614 * Create a posix group with the given name.
2615 * This group will be added to the /etc/group file.
2616 */
2617 static int
2618 smb_lgrp_pgrp_add(char *group)
2619 {
2620 FILE *etcgrp;
2621 FILE *etctmp;
2622 int o_mask, gret;
2623 int newdone = 0;
2624 struct stat sb;
2625 char buf[SMB_LGRP_PGRP_GRPBUFSIZ];
2626 gid_t gid;
2627 int rc = 0;
2628
2629 rc = smb_lgrp_pgrp_valid_gname(group);
2630 if ((rc == SMB_LGRP_PGRP_INVALID) || (rc == SMB_LGRP_PGRP_NOTUNIQUE))
2631 return (-1);
2632
2633 if ((gret = smb_lgrp_pgrp_findnextgid()) < 0)
2634 return (-1);
2635 gid = gret;
2636
2637 if ((etcgrp = fopen(SMB_LGRP_PGRP_GROUP, "r")) == NULL)
2638 return (-1);
2639
2640 if (fstat(fileno(etcgrp), &sb) < 0)
2641 sb.st_mode = S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH;
2642
2643 o_mask = umask(077);
2644 etctmp = fopen(SMB_LGRP_PGRP_GRPTMP, "w+");
2645 (void) umask(o_mask);
2646
2647 if (etctmp == NULL) {
2648 (void) fclose(etcgrp);
2649 return (-1);
2650 }
2651
2652 if (lockf(fileno(etctmp), F_LOCK, 0) != 0) {
2653 (void) fclose(etcgrp);
2654 (void) fclose(etctmp);
2655 (void) unlink(SMB_LGRP_PGRP_GRPTMP);
|
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
46 * therefore the index is 0
47 */
48 #define SMB_LGRP_LOCAL_IDX 0
49 #define SMB_LGRP_BUILTIN_IDX 1
50
51 #define SMB_LGRP_DB_NAME "/var/smb/smbgroup.db"
52 #define SMB_LGRP_DB_TIMEOUT 3000 /* in millisecond */
53 #define SMB_LGRP_DB_VERMAJOR 1
54 #define SMB_LGRP_DB_VERMINOR 0
55 #define SMB_LGRP_DB_MAGIC 0x4C475250 /* LGRP */
56
57 #define SMB_LGRP_DB_ORD 1 /* open read-only */
58 #define SMB_LGRP_DB_ORW 2 /* open read/write */
59
60 #define SMB_LGRP_DB_ADDMEMBER 1
61 #define SMB_LGRP_DB_DELMEMBER 2
62
108 #define SMB_LGRP_GTBL_SIDTYP 3
109 #define SMB_LGRP_GTBL_SIDATR 4
110 #define SMB_LGRP_GTBL_CMNT 5
111 #define SMB_LGRP_GTBL_NPRIVS 6
112 #define SMB_LGRP_GTBL_PRIVS 7
113 #define SMB_LGRP_GTBL_NMEMBS 8
114 #define SMB_LGRP_GTBL_MEMBS 9
115
116 #define SMB_LGRP_INFO_NONE 0x00
117 #define SMB_LGRP_INFO_NAME 0x01
118 #define SMB_LGRP_INFO_CMNT 0x02
119 #define SMB_LGRP_INFO_SID 0x04
120 #define SMB_LGRP_INFO_PRIV 0x08
121 #define SMB_LGRP_INFO_MEMB 0x10
122 #define SMB_LGRP_INFO_ALL 0x1F
123
124 #define SMB_LGRP_PGRP_GRPTMP "/etc/gtmp"
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 {
2530
2531 for (c = *ptr; c != NULL; ptr++, c = *ptr) {
2532 len++;
2533 if (!isprint(c) || (c == ':') || (c == '\n'))
2534 return (SMB_LGRP_PGRP_INVALID);
2535
2536 if (!(islower(c) || isdigit(c)))
2537 badchar++;
2538 }
2539
2540 if ((len > SMB_LGRP_PGRP_MAXGLEN - 1) || (badchar != 0))
2541 return (SMB_LGRP_PGRP_INVALID);
2542
2543 if (getgrnam(group) != NULL)
2544 return (SMB_LGRP_PGRP_NOTUNIQUE);
2545
2546 return (SMB_LGRP_PGRP_UNIQUE);
2547 }
2548
2549 /*
2550 * smb_lgrp_pgrp_add
2551 *
2552 * Create a posix group with the given name.
2553 * This group will be added to the /etc/group file.
2554 */
2555 static int
2556 smb_lgrp_pgrp_add(char *group)
2557 {
2558 FILE *etcgrp;
2559 FILE *etctmp;
2560 int o_mask;
2561 int newdone = 0;
2562 struct stat sb;
2563 char buf[SMB_LGRP_PGRP_GRPBUFSIZ];
2564 gid_t gid;
2565 int rc = 0;
2566
2567 rc = smb_lgrp_pgrp_valid_gname(group);
2568 if ((rc == SMB_LGRP_PGRP_INVALID) || (rc == SMB_LGRP_PGRP_NOTUNIQUE))
2569 return (-1);
2570
2571 if ((findnextgid(SMB_LGRP_PGRP_DEFRID, MAXUID, &gid)) != 0)
2572 return (-1);
2573
2574 if ((etcgrp = fopen(SMB_LGRP_PGRP_GROUP, "r")) == NULL)
2575 return (-1);
2576
2577 if (fstat(fileno(etcgrp), &sb) < 0)
2578 sb.st_mode = S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH;
2579
2580 o_mask = umask(077);
2581 etctmp = fopen(SMB_LGRP_PGRP_GRPTMP, "w+");
2582 (void) umask(o_mask);
2583
2584 if (etctmp == NULL) {
2585 (void) fclose(etcgrp);
2586 return (-1);
2587 }
2588
2589 if (lockf(fileno(etctmp), F_LOCK, 0) != 0) {
2590 (void) fclose(etcgrp);
2591 (void) fclose(etctmp);
2592 (void) unlink(SMB_LGRP_PGRP_GRPTMP);
|