1/* 2 Unix SMB/CIFS implementation. 3 4 interface functions for the sam database 5 6 Copyright (C) Andrew Tridgell 2004 7 Copyright (C) Volker Lendecke 2004 8 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2006 9 10 This program is free software; you can redistribute it and/or modify 11 it under the terms of the GNU General Public License as published by 12 the Free Software Foundation; either version 3 of the License, or 13 (at your option) any later version. 14 15 This program is distributed in the hope that it will be useful, 16 but WITHOUT ANY WARRANTY; without even the implied warranty of 17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 GNU General Public License for more details. 19 20 You should have received a copy of the GNU General Public License 21 along with this program. If not, see <http://www.gnu.org/licenses/>. 22*/ 23 24#include "includes.h" 25#include "librpc/gen_ndr/ndr_netlogon.h" 26#include "librpc/gen_ndr/ndr_misc.h" 27#include "librpc/gen_ndr/ndr_security.h" 28#include "lib/events/events.h" 29#include "lib/ldb/include/ldb.h" 30#include "lib/ldb/include/ldb_errors.h" 31#include "libcli/security/security.h" 32#include "libcli/auth/libcli_auth.h" 33#include "libcli/ldap/ldap_ndr.h" 34#include "system/time.h" 35#include "system/filesys.h" 36#include "ldb_wrap.h" 37#include "../lib/util/util_ldb.h" 38#include "dsdb/samdb/samdb.h" 39#include "../libds/common/flags.h" 40#include "param/param.h" 41#include "lib/events/events.h" 42#include "auth/credentials/credentials.h" 43#include "param/secrets.h" 44 45char *samdb_relative_path(struct ldb_context *ldb, 46 TALLOC_CTX *mem_ctx, 47 const char *name) 48{ 49 const char *base_url = 50 (const char *)ldb_get_opaque(ldb, "ldb_url"); 51 char *path, *p, *full_name; 52 if (name == NULL) { 53 return NULL; 54 } 55 if (name[0] == 0 || name[0] == '/' || strstr(name, ":/")) { 56 return talloc_strdup(mem_ctx, name); 57 } 58 path = talloc_strdup(mem_ctx, base_url); 59 if (path == NULL) { 60 return NULL; 61 } 62 if ( (p = strrchr(path, '/')) != NULL) { 63 p[0] = '\0'; 64 full_name = talloc_asprintf(mem_ctx, "%s/%s", path, name); 65 } else { 66 full_name = talloc_asprintf(mem_ctx, "./%s", name); 67 } 68 talloc_free(path); 69 return full_name; 70} 71 72struct cli_credentials *samdb_credentials(TALLOC_CTX *mem_ctx, 73 struct tevent_context *event_ctx, 74 struct loadparm_context *lp_ctx) 75{ 76 struct cli_credentials *cred = cli_credentials_init(mem_ctx); 77 if (!cred) { 78 return NULL; 79 } 80 cli_credentials_set_conf(cred, lp_ctx); 81 82 /* We don't want to use krb5 to talk to our samdb - recursion 83 * here would be bad, and this account isn't in the KDC 84 * anyway */ 85 cli_credentials_set_kerberos_state(cred, CRED_DONT_USE_KERBEROS); 86 87 if (!NT_STATUS_IS_OK(cli_credentials_set_secrets(cred, event_ctx, lp_ctx, NULL, NULL, 88 SECRETS_LDAP_FILTER))) { 89 /* Perfectly OK - if not against an LDAP backend */ 90 return NULL; 91 } 92 return cred; 93} 94 95/* 96 connect to the SAM database 97 return an opaque context pointer on success, or NULL on failure 98 */ 99struct ldb_context *samdb_connect(TALLOC_CTX *mem_ctx, 100 struct tevent_context *ev_ctx, 101 struct loadparm_context *lp_ctx, 102 struct auth_session_info *session_info) 103{ 104 struct ldb_context *ldb; 105 ldb = ldb_wrap_connect(mem_ctx, ev_ctx, lp_ctx, 106 lp_sam_url(lp_ctx), session_info, 107 samdb_credentials(mem_ctx, ev_ctx, lp_ctx), 108 0, NULL); 109 if (!ldb) { 110 return NULL; 111 } 112 dsdb_make_schema_global(ldb); 113 return ldb; 114} 115 116 117/**************************************************************************** 118 Create the SID list for this user. 119****************************************************************************/ 120NTSTATUS security_token_create(TALLOC_CTX *mem_ctx, 121 struct tevent_context *ev_ctx, 122 struct loadparm_context *lp_ctx, 123 struct dom_sid *user_sid, 124 struct dom_sid *group_sid, 125 int n_groupSIDs, 126 struct dom_sid **groupSIDs, 127 bool is_authenticated, 128 struct security_token **token) 129{ 130 struct security_token *ptoken; 131 int i; 132 NTSTATUS status; 133 134 ptoken = security_token_initialise(mem_ctx); 135 NT_STATUS_HAVE_NO_MEMORY(ptoken); 136 137 ptoken->sids = talloc_array(ptoken, struct dom_sid *, n_groupSIDs + 5); 138 NT_STATUS_HAVE_NO_MEMORY(ptoken->sids); 139 140 ptoken->user_sid = talloc_reference(ptoken, user_sid); 141 ptoken->group_sid = talloc_reference(ptoken, group_sid); 142 ptoken->privilege_mask = 0; 143 144 ptoken->sids[0] = ptoken->user_sid; 145 ptoken->sids[1] = ptoken->group_sid; 146 147 /* 148 * Finally add the "standard" SIDs. 149 * The only difference between guest and "anonymous" 150 * is the addition of Authenticated_Users. 151 */ 152 ptoken->sids[2] = dom_sid_parse_talloc(ptoken->sids, SID_WORLD); 153 NT_STATUS_HAVE_NO_MEMORY(ptoken->sids[2]); 154 ptoken->sids[3] = dom_sid_parse_talloc(ptoken->sids, SID_NT_NETWORK); 155 NT_STATUS_HAVE_NO_MEMORY(ptoken->sids[3]); 156 ptoken->num_sids = 4; 157 158 if (is_authenticated) { 159 ptoken->sids[4] = dom_sid_parse_talloc(ptoken->sids, SID_NT_AUTHENTICATED_USERS); 160 NT_STATUS_HAVE_NO_MEMORY(ptoken->sids[4]); 161 ptoken->num_sids++; 162 } 163 164 for (i = 0; i < n_groupSIDs; i++) { 165 size_t check_sid_idx; 166 for (check_sid_idx = 1; 167 check_sid_idx < ptoken->num_sids; 168 check_sid_idx++) { 169 if (dom_sid_equal(ptoken->sids[check_sid_idx], groupSIDs[i])) { 170 break; 171 } 172 } 173 174 if (check_sid_idx == ptoken->num_sids) { 175 ptoken->sids[ptoken->num_sids++] = talloc_reference(ptoken->sids, groupSIDs[i]); 176 } 177 } 178 179 /* setup the privilege mask for this token */ 180 status = samdb_privilege_setup(ev_ctx, lp_ctx, ptoken); 181 if (!NT_STATUS_IS_OK(status)) { 182 talloc_free(ptoken); 183 return status; 184 } 185 186 security_token_debug(10, ptoken); 187 188 *token = ptoken; 189 190 return NT_STATUS_OK; 191} 192