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 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
23 * Copyright 2014 Nexenta Systems, Inc. All rights reserved.
24 */
25
26 #include <sys/list.h>
27 #include <assert.h>
28 #include <alloca.h>
29 #include <door.h>
30 #include <errno.h>
31 #include <syslog.h>
32 #include <unistd.h>
33 #include <stdio.h>
34 #include <synch.h>
35 #include <string.h>
36 #include <stdlib.h>
37 #include <sys/stat.h>
38 #include <fcntl.h>
39 #include <pthread.h>
40 #include <strings.h>
41 #include <note.h>
42 #include <smbsrv/smb_door.h>
43 #include <smbsrv/smb_xdr.h>
86
87 smbd_doorop_t smbd_doorops[] = {
88 { SMB_DR_NULL, smbd_dop_null },
89 { SMB_DR_ASYNC_RESPONSE, smbd_dop_async_response },
90 { SMB_DR_USER_AUTH_LOGON, smbd_dop_user_auth_logon },
91 { SMB_DR_USER_NONAUTH_LOGON, smbd_dop_user_nonauth_logon },
92 { SMB_DR_USER_AUTH_LOGOFF, smbd_dop_user_auth_logoff },
93 { SMB_DR_LOOKUP_SID, smbd_dop_lookup_sid },
94 { SMB_DR_LOOKUP_NAME, smbd_dop_lookup_name },
95 { SMB_DR_JOIN, smbd_dop_join },
96 { SMB_DR_GET_DCINFO, smbd_dop_get_dcinfo },
97 { SMB_DR_VSS_GET_COUNT, smbd_dop_vss_get_count },
98 { SMB_DR_VSS_GET_SNAPSHOTS, smbd_dop_vss_get_snapshots },
99 { SMB_DR_VSS_MAP_GMTTOKEN, smbd_dop_vss_map_gmttoken },
100 { SMB_DR_ADS_FIND_HOST, smbd_dop_ads_find_host },
101 { SMB_DR_QUOTA_QUERY, smbd_dop_quota_query },
102 { SMB_DR_QUOTA_SET, smbd_dop_quota_set },
103 { SMB_DR_DFS_GET_REFERRALS, smbd_dop_dfs_get_referrals },
104 { SMB_DR_SHR_HOSTACCESS, smbd_dop_shr_hostaccess },
105 { SMB_DR_SHR_EXEC, smbd_dop_shr_exec },
106 { SMB_DR_NOTIFY_DC_CHANGED, smbd_dop_notify_dc_changed }
107 };
108
109 static int smbd_ndoorop = (sizeof (smbd_doorops) / sizeof (smbd_doorops[0]));
110
111 static smbd_doorsvc_t smbd_doorsvc;
112 static int smbd_door_fd = -1;
113 static int smbd_door_cookie = 0x534D4244; /* SMBD */
114 static smbd_door_t smbd_door_sdh;
115 static char *smbd_door_name = NULL;
116
117 static void smbd_door_dispatch(void *, char *, size_t, door_desc_t *, uint_t);
118 static int smbd_door_dispatch_async(smbd_arg_t *);
119 static void smbd_door_release_async(smbd_arg_t *);
120
121 /*
122 * Start the smbd door service. Create and bind to a door.
123 * Returns 0 on success. Otherwise, -1.
124 */
125 int
126 smbd_door_start(void)
564 if (smb_common_decode(arg->data, arg->datalen,
565 xdr_uint32_t, &sid) != 0)
566 return (SMB_DOP_DECODE_ERROR);
567
568 smbd_user_auth_logoff(sid);
569 return (SMB_DOP_SUCCESS);
570 }
571
572 /*
573 * Obtains an access token on successful user authentication.
574 */
575 static int
576 smbd_dop_user_auth_logon(smbd_arg_t *arg)
577 {
578 _NOTE(ARGUNUSED(arg))
579
580 /* No longer used */
581 return (SMB_DOP_EMPTYBUF);
582 }
583
584 static int
585 smbd_dop_lookup_name(smbd_arg_t *arg)
586 {
587 smb_domain_t dinfo;
588 smb_account_t ainfo;
589 lsa_account_t acct;
590 char buf[MAXNAMELEN];
591
592 bzero(&acct, sizeof (lsa_account_t));
593
594 if (smb_common_decode(arg->data, arg->datalen,
595 lsa_account_xdr, &acct) != 0)
596 return (SMB_DOP_DECODE_ERROR);
597
598 if (*acct.a_domain == '\0')
599 (void) snprintf(buf, MAXNAMELEN, "%s", acct.a_name);
600 else if (strchr(acct.a_domain, '.') != NULL)
601 (void) snprintf(buf, MAXNAMELEN, "%s@%s", acct.a_name,
602 acct.a_domain);
603 else
604 (void) snprintf(buf, MAXNAMELEN, "%s\\%s", acct.a_domain,
605 acct.a_name);
606
607 acct.a_status = lsa_lookup_name(buf, acct.a_sidtype, &ainfo);
608 if (acct.a_status == NT_STATUS_SUCCESS) {
609 acct.a_sidtype = ainfo.a_type;
610 smb_sid_tostr(ainfo.a_sid, acct.a_sid);
611 (void) strlcpy(acct.a_name, ainfo.a_name, MAXNAMELEN);
612
613 if (smb_domain_lookup_name(ainfo.a_domain, &dinfo))
614 (void) strlcpy(acct.a_domain, dinfo.di_fqname,
615 MAXNAMELEN);
616 else
617 (void) strlcpy(acct.a_domain, ainfo.a_domain,
618 MAXNAMELEN);
619 smb_account_free(&ainfo);
620 }
621
622 arg->rbuf = smb_common_encode(&acct, lsa_account_xdr, &arg->rsize);
623
624 if (arg->rbuf == NULL)
625 return (SMB_DOP_ENCODE_ERROR);
626 return (SMB_DOP_SUCCESS);
627 }
628
629 static int
630 smbd_dop_lookup_sid(smbd_arg_t *arg)
631 {
632 smb_domain_t dinfo;
633 smb_account_t ainfo;
634 lsa_account_t acct;
635 smb_sid_t *sid;
636
637 bzero(&acct, sizeof (lsa_account_t));
638
639 if (smb_common_decode(arg->data, arg->datalen,
640 lsa_account_xdr, &acct) != 0)
641 return (SMB_DOP_DECODE_ERROR);
642
643 sid = smb_sid_fromstr(acct.a_sid);
644 acct.a_status = lsa_lookup_sid(sid, &ainfo);
645 smb_sid_free(sid);
646
647 if (acct.a_status == NT_STATUS_SUCCESS) {
648 acct.a_sidtype = ainfo.a_type;
649 smb_sid_tostr(ainfo.a_sid, acct.a_sid);
650 (void) strlcpy(acct.a_name, ainfo.a_name, MAXNAMELEN);
651
652 if (smb_domain_lookup_name(ainfo.a_domain, &dinfo))
653 (void) strlcpy(acct.a_domain, dinfo.di_fqname,
654 MAXNAMELEN);
655 else
656 (void) strlcpy(acct.a_domain, ainfo.a_domain,
657 MAXNAMELEN);
658
659 smb_account_free(&ainfo);
660 }
661
662 arg->rbuf = smb_common_encode(&acct, lsa_account_xdr, &arg->rsize);
663
664 if (arg->rbuf == NULL)
|
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 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
23 * Copyright 2019 Nexenta Systems, Inc. All rights reserved.
24 */
25
26 #include <sys/list.h>
27 #include <assert.h>
28 #include <alloca.h>
29 #include <door.h>
30 #include <errno.h>
31 #include <syslog.h>
32 #include <unistd.h>
33 #include <stdio.h>
34 #include <synch.h>
35 #include <string.h>
36 #include <stdlib.h>
37 #include <sys/stat.h>
38 #include <fcntl.h>
39 #include <pthread.h>
40 #include <strings.h>
41 #include <note.h>
42 #include <smbsrv/smb_door.h>
43 #include <smbsrv/smb_xdr.h>
86
87 smbd_doorop_t smbd_doorops[] = {
88 { SMB_DR_NULL, smbd_dop_null },
89 { SMB_DR_ASYNC_RESPONSE, smbd_dop_async_response },
90 { SMB_DR_USER_AUTH_LOGON, smbd_dop_user_auth_logon },
91 { SMB_DR_USER_NONAUTH_LOGON, smbd_dop_user_nonauth_logon },
92 { SMB_DR_USER_AUTH_LOGOFF, smbd_dop_user_auth_logoff },
93 { SMB_DR_LOOKUP_SID, smbd_dop_lookup_sid },
94 { SMB_DR_LOOKUP_NAME, smbd_dop_lookup_name },
95 { SMB_DR_JOIN, smbd_dop_join },
96 { SMB_DR_GET_DCINFO, smbd_dop_get_dcinfo },
97 { SMB_DR_VSS_GET_COUNT, smbd_dop_vss_get_count },
98 { SMB_DR_VSS_GET_SNAPSHOTS, smbd_dop_vss_get_snapshots },
99 { SMB_DR_VSS_MAP_GMTTOKEN, smbd_dop_vss_map_gmttoken },
100 { SMB_DR_ADS_FIND_HOST, smbd_dop_ads_find_host },
101 { SMB_DR_QUOTA_QUERY, smbd_dop_quota_query },
102 { SMB_DR_QUOTA_SET, smbd_dop_quota_set },
103 { SMB_DR_DFS_GET_REFERRALS, smbd_dop_dfs_get_referrals },
104 { SMB_DR_SHR_HOSTACCESS, smbd_dop_shr_hostaccess },
105 { SMB_DR_SHR_EXEC, smbd_dop_shr_exec },
106 { SMB_DR_NOTIFY_DC_CHANGED, smbd_dop_notify_dc_changed },
107 { SMB_DR_LOOKUP_LSID, smbd_dop_lookup_sid },
108 { SMB_DR_LOOKUP_LNAME, smbd_dop_lookup_name }
109 };
110
111 static int smbd_ndoorop = (sizeof (smbd_doorops) / sizeof (smbd_doorops[0]));
112
113 static smbd_doorsvc_t smbd_doorsvc;
114 static int smbd_door_fd = -1;
115 static int smbd_door_cookie = 0x534D4244; /* SMBD */
116 static smbd_door_t smbd_door_sdh;
117 static char *smbd_door_name = NULL;
118
119 static void smbd_door_dispatch(void *, char *, size_t, door_desc_t *, uint_t);
120 static int smbd_door_dispatch_async(smbd_arg_t *);
121 static void smbd_door_release_async(smbd_arg_t *);
122
123 /*
124 * Start the smbd door service. Create and bind to a door.
125 * Returns 0 on success. Otherwise, -1.
126 */
127 int
128 smbd_door_start(void)
566 if (smb_common_decode(arg->data, arg->datalen,
567 xdr_uint32_t, &sid) != 0)
568 return (SMB_DOP_DECODE_ERROR);
569
570 smbd_user_auth_logoff(sid);
571 return (SMB_DOP_SUCCESS);
572 }
573
574 /*
575 * Obtains an access token on successful user authentication.
576 */
577 static int
578 smbd_dop_user_auth_logon(smbd_arg_t *arg)
579 {
580 _NOTE(ARGUNUSED(arg))
581
582 /* No longer used */
583 return (SMB_DOP_EMPTYBUF);
584 }
585
586 /*
587 * SMB_DR_LOOKUP_NAME,
588 * SMB_DR_LOOKUP_LNAME (local-only, for idmap)
589 */
590 static int
591 smbd_dop_lookup_name(smbd_arg_t *arg)
592 {
593 smb_domain_t dinfo;
594 smb_account_t ainfo;
595 lsa_account_t acct;
596 char buf[MAXNAMELEN];
597
598 bzero(&acct, sizeof (lsa_account_t));
599
600 if (smb_common_decode(arg->data, arg->datalen,
601 lsa_account_xdr, &acct) != 0)
602 return (SMB_DOP_DECODE_ERROR);
603
604 if (*acct.a_domain == '\0')
605 (void) snprintf(buf, MAXNAMELEN, "%s", acct.a_name);
606 else if (strchr(acct.a_domain, '.') != NULL)
607 (void) snprintf(buf, MAXNAMELEN, "%s@%s", acct.a_name,
608 acct.a_domain);
609 else
610 (void) snprintf(buf, MAXNAMELEN, "%s\\%s", acct.a_domain,
611 acct.a_name);
612
613 switch (arg->hdr.dh_op) {
614 case SMB_DR_LOOKUP_NAME:
615 acct.a_status = lsa_lookup_name(buf, acct.a_sidtype, &ainfo);
616 break;
617
618 case SMB_DR_LOOKUP_LNAME:
619 /*
620 * Basically for idmap. Don't call out to AD.
621 */
622 acct.a_status = lsa_lookup_lname(buf, acct.a_sidtype, &ainfo);
623 break;
624
625 default:
626 assert(!"arg->hdr.dh_op");
627 acct.a_status = NT_STATUS_INTERNAL_ERROR;
628 break;
629 }
630
631 if (acct.a_status == NT_STATUS_SUCCESS) {
632 acct.a_sidtype = ainfo.a_type;
633 smb_sid_tostr(ainfo.a_sid, acct.a_sid);
634 (void) strlcpy(acct.a_name, ainfo.a_name, MAXNAMELEN);
635
636 if (smb_domain_lookup_name(ainfo.a_domain, &dinfo))
637 (void) strlcpy(acct.a_domain, dinfo.di_fqname,
638 MAXNAMELEN);
639 else
640 (void) strlcpy(acct.a_domain, ainfo.a_domain,
641 MAXNAMELEN);
642 smb_account_free(&ainfo);
643 }
644
645 arg->rbuf = smb_common_encode(&acct, lsa_account_xdr, &arg->rsize);
646
647 if (arg->rbuf == NULL)
648 return (SMB_DOP_ENCODE_ERROR);
649 return (SMB_DOP_SUCCESS);
650 }
651
652 /*
653 * SMB_DR_LOOKUP_SID,
654 * SMB_DR_LOOKUP_LSID (local-only, for idmap)
655 */
656 static int
657 smbd_dop_lookup_sid(smbd_arg_t *arg)
658 {
659 smb_domain_t dinfo;
660 smb_account_t ainfo;
661 lsa_account_t acct;
662 smb_sid_t *sid;
663
664 bzero(&acct, sizeof (lsa_account_t));
665
666 if (smb_common_decode(arg->data, arg->datalen,
667 lsa_account_xdr, &acct) != 0)
668 return (SMB_DOP_DECODE_ERROR);
669
670 sid = smb_sid_fromstr(acct.a_sid);
671
672 switch (arg->hdr.dh_op) {
673 case SMB_DR_LOOKUP_SID:
674 acct.a_status = lsa_lookup_sid(sid, &ainfo);
675 break;
676
677 case SMB_DR_LOOKUP_LSID:
678 /*
679 * Basically for idmap. Don't call out to AD.
680 */
681 acct.a_status = lsa_lookup_lsid(sid, &ainfo);
682 break;
683
684 default:
685 assert(!"arg->hdr.dh_op");
686 acct.a_status = NT_STATUS_INTERNAL_ERROR;
687 break;
688 }
689
690 smb_sid_free(sid);
691
692 if (acct.a_status == NT_STATUS_SUCCESS) {
693 acct.a_sidtype = ainfo.a_type;
694 smb_sid_tostr(ainfo.a_sid, acct.a_sid);
695 (void) strlcpy(acct.a_name, ainfo.a_name, MAXNAMELEN);
696
697 if (smb_domain_lookup_name(ainfo.a_domain, &dinfo))
698 (void) strlcpy(acct.a_domain, dinfo.di_fqname,
699 MAXNAMELEN);
700 else
701 (void) strlcpy(acct.a_domain, ainfo.a_domain,
702 MAXNAMELEN);
703
704 smb_account_free(&ainfo);
705 }
706
707 arg->rbuf = smb_common_encode(&acct, lsa_account_xdr, &arg->rsize);
708
709 if (arg->rbuf == NULL)
|