/** * The challenge from the target server, when operating in security=server **/ static NTSTATUS server_get_challenge(struct auth_method_context *ctx, TALLOC_CTX *mem_ctx, uint8_t chal[8]) { struct smb_composite_connect io; struct smbcli_options smb_options; const char **host_list; NTSTATUS status; /* Make a connection to the target server, found by 'password server' in smb.conf */ lp_smbcli_options(ctx->auth_ctx->lp_ctx, &smb_options); /* Make a negprot, WITHOUT SPNEGO, so we get a challenge nice an easy */ io.in.options.use_spnego = false; /* Hope we don't get * (the default), as this won't work... */ host_list = lp_passwordserver(ctx->auth_ctx->lp_ctx); if (!host_list) { return NT_STATUS_INTERNAL_ERROR; } io.in.dest_host = host_list[0]; if (strequal(io.in.dest_host, "*")) { return NT_STATUS_INTERNAL_ERROR; } io.in.dest_ports = lp_smb_ports(ctx->auth_ctx->lp_ctx); io.in.socket_options = lp_socket_options(ctx->auth_ctx->lp_ctx); io.in.gensec_settings = lp_gensec_settings(mem_ctx, ctx->auth_ctx->lp_ctx); io.in.called_name = strupper_talloc(mem_ctx, io.in.dest_host); /* We don't want to get as far as the session setup */ io.in.credentials = cli_credentials_init_anon(mem_ctx); cli_credentials_set_workstation(io.in.credentials, lp_netbios_name(ctx->auth_ctx->lp_ctx), CRED_SPECIFIED); io.in.service = NULL; io.in.workgroup = ""; /* only used with SPNEGO, disabled above */ io.in.options = smb_options; io.in.iconv_convenience = lp_iconv_convenience(ctx->auth_ctx->lp_ctx); lp_smbcli_session_options(ctx->auth_ctx->lp_ctx, &io.in.session_options); status = smb_composite_connect(&io, mem_ctx, lp_resolve_context(ctx->auth_ctx->lp_ctx), ctx->auth_ctx->event_ctx); NT_STATUS_NOT_OK_RETURN(status); if (io.out.tree->session->transport->negotiate.secblob.length != 8) { return NT_STATUS_INTERNAL_ERROR; } memcpy(chal, io.out.tree->session->transport->negotiate.secblob.data, 8); ctx->private_data = talloc_steal(ctx, io.out.tree->session); return NT_STATUS_OK; }
static NTSTATUS schannel_store_session_key_tdb(struct tdb_wrap *tdb_sc, TALLOC_CTX *mem_ctx, struct netlogon_creds_CredentialState *creds) { enum ndr_err_code ndr_err; DATA_BLOB blob; TDB_DATA value; int ret; char *keystr; char *name_upper; name_upper = strupper_talloc(mem_ctx, creds->computer_name); if (!name_upper) { return NT_STATUS_NO_MEMORY; } keystr = talloc_asprintf(mem_ctx, "%s/%s", SECRETS_SCHANNEL_STATE, name_upper); TALLOC_FREE(name_upper); if (!keystr) { return NT_STATUS_NO_MEMORY; } ndr_err = ndr_push_struct_blob(&blob, mem_ctx, creds, (ndr_push_flags_fn_t)ndr_push_netlogon_creds_CredentialState); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { talloc_free(keystr); return ndr_map_error2ntstatus(ndr_err); } value.dptr = blob.data; value.dsize = blob.length; ret = tdb_store_bystring(tdb_sc->tdb, keystr, value, TDB_REPLACE); if (ret != TDB_SUCCESS) { DEBUG(0,("Unable to add %s to session key db - %s\n", keystr, tdb_errorstr_compat(tdb_sc->tdb))); talloc_free(keystr); return NT_STATUS_INTERNAL_DB_CORRUPTION; } DEBUG(3,("schannel_store_session_key_tdb: stored schannel info with key %s\n", keystr)); if (DEBUGLEVEL >= 10) { NDR_PRINT_DEBUG(netlogon_creds_CredentialState, creds); } talloc_free(keystr); return NT_STATUS_OK; }
/** * Set the realm for this credentials context, and force it to * uppercase for the sainity of our local kerberos libraries */ _PUBLIC_ bool cli_credentials_set_realm(struct cli_credentials *cred, const char *val, enum credentials_obtained obtained) { if (obtained >= cred->realm_obtained) { cred->realm = strupper_talloc(cred, val); cred->realm_obtained = obtained; cli_credentials_invalidate_ccache(cred, cred->realm_obtained); return true; } return false; }
static int ejs_tree_connect(MprVarHandle eid, int argc, char **argv) { struct cli_credentials *creds; struct smb_composite_connect io; struct smbcli_tree *tree; char *hostname, *sharename; NTSTATUS result; TALLOC_CTX *mem_ctx; if (argc != 2) { ejsSetErrorMsg(eid, "tree_connect(): invalid number of args"); return -1; } /* Set up host, share destination */ mem_ctx = talloc_new(mprMemCtx()); smbcli_parse_unc(argv[0], mem_ctx, &hostname, &sharename); /* Set up credentials */ creds = cli_credentials_init(NULL); cli_credentials_set_conf(creds); cli_credentials_parse_string(creds, argv[1], CRED_SPECIFIED); /* Do connect */ io.in.dest_host = hostname; io.in.port = 0; io.in.called_name = strupper_talloc(mem_ctx, hostname); io.in.service = sharename; io.in.service_type = "?????"; io.in.credentials = creds; io.in.fallback_to_anonymous = False; io.in.workgroup = lp_workgroup(); result = smb_composite_connect(&io, mem_ctx, NULL); tree = io.out.tree; talloc_free(mem_ctx); if (!NT_STATUS_IS_OK(result)) { mpr_Return(eid, mprNTSTATUS(result)); return 0; } mpr_Return(eid, mprCreatePtrVar(tree)); return 0; }
bool torture_nbt_get_name(struct torture_context *tctx, struct nbt_name *name, const char **address) { make_nbt_name_server(name, strupper_talloc(tctx, torture_setting_string(tctx, "host", NULL))); /* do an initial name resolution to find its IP */ torture_assert_ntstatus_ok(tctx, resolve_name_ex(lpcfg_resolve_context(tctx->lp_ctx), 0, 0, name, tctx, address, tctx->ev), talloc_asprintf(tctx, "Failed to resolve %s", name->name)); return true; }
_PUBLIC_ bool cli_credentials_set_domain(struct cli_credentials *cred, const char *val, enum credentials_obtained obtained) { if (obtained >= cred->domain_obtained) { /* it is important that the domain be in upper case, * particularly for the sensitive NTLMv2 * calculations */ cred->domain = strupper_talloc(cred, val); cred->domain_obtained = obtained; /* setting domain does not mean we have to invalidate ccache * because domain in not used for Kerberos operations. * If ccache invalidation is required, one will anyway specify * a password to kinit, and that will force invalidation of the ccache */ return true; } return false; }
static bool torture_winbind_struct_netbios_name(struct torture_context *torture) { struct winbindd_response rep; const char *expected; ZERO_STRUCT(rep); torture_comment(torture, "Running WINBINDD_NETBIOS_NAME (struct based)\n"); DO_STRUCT_REQ_REP(WINBINDD_NETBIOS_NAME, NULL, &rep); expected = torture_setting_string(torture, "winbindd_netbios_name", lpcfg_netbios_name(torture->lp_ctx)); expected = strupper_talloc(torture, expected); torture_assert_str_equal(torture, rep.data.netbios_name, expected, "winbindd's netbios name doesn't match"); return true; }
static int fix_dn(struct ldb_dn *dn) { int i, ret; char *upper_rdn_attr; for (i=0; i < ldb_dn_get_comp_num(dn); i++) { /* We need the attribute name in upper case */ upper_rdn_attr = strupper_talloc(dn, ldb_dn_get_component_name(dn, i)); if (!upper_rdn_attr) { return LDB_ERR_OPERATIONS_ERROR; } /* And replace it with CN=foo (we need the attribute in upper case */ ret = ldb_dn_set_component(dn, i, upper_rdn_attr, *ldb_dn_get_component_val(dn, i)); talloc_free(upper_rdn_attr); if (ret != LDB_SUCCESS) { return ret; } } return LDB_SUCCESS; }
bool E_deshash(const char *passwd, uint8_t p16[16]) { bool ret; uint8_t dospwd[14]; TALLOC_CTX *frame = talloc_stackframe(); size_t converted_size; char *tmpbuf; ZERO_STRUCT(dospwd); tmpbuf = strupper_talloc(frame, passwd); if (tmpbuf == NULL) { /* Too many callers don't check this result, we need to fill in the buffer with something */ strlcpy((char *)dospwd, passwd ? passwd : "", sizeof(dospwd)); E_P16(dospwd, p16); talloc_free(frame); return false; } ZERO_STRUCT(dospwd); ret = convert_string_error(CH_UNIX, CH_DOS, tmpbuf, strlen(tmpbuf), dospwd, sizeof(dospwd), &converted_size); talloc_free(frame); /* Only the first 14 chars are considered, password need not * be null terminated. We do this in the error and success * case to avoid returning a fixed 'password' buffer, but * callers should not use it when E_deshash returns false */ E_P16((const uint8_t *)dospwd, p16); ZERO_STRUCT(dospwd); return ret; }
static WERROR cmd_predef(struct regshell_context *ctx, int argc, char **argv) { struct registry_key *ret = NULL; if (argc < 2) { fprintf(stderr, "Usage: predef predefined-key-name\n"); } else if (!ctx) { fprintf(stderr, "No full registry loaded, no predefined keys defined\n"); } else { WERROR error = reg_get_predefined_key_by_name(ctx->registry, argv[1], &ret); if (!W_ERROR_IS_OK(error)) { fprintf(stderr, "Error opening predefined key %s: %s\n", argv[1], win_errstr(error)); return error; } ctx->predef = strupper_talloc(ctx, argv[1]); ctx->current = ret; ctx->root = ret; } return WERR_OK; }
/** * Fill in credentials for the machine trust account, from the * secrets.ldb or passed in handle to secrets.tdb (perhaps in CTDB). * * This version is used in parts of the code that can link in the * CTDB dbwrap backend, by passing down the already open handle. * * @param cred Credentials structure to fill in * @param db_ctx dbwrap context for secrets.tdb * @retval NTSTATUS error detailing any failure */ _PUBLIC_ NTSTATUS cli_credentials_set_machine_account_db_ctx(struct cli_credentials *cred, struct loadparm_context *lp_ctx, struct db_context *db_ctx) { NTSTATUS status; char *filter; char *error_string = NULL; const char *domain; bool secrets_tdb_password_more_recent; time_t secrets_tdb_lct = 0; char *secrets_tdb_password = NULL; char *secrets_tdb_old_password = NULL; uint32_t secrets_tdb_secure_channel_type = SEC_CHAN_NULL; char *keystr; char *keystr_upper = NULL; TALLOC_CTX *tmp_ctx = talloc_named(cred, 0, "cli_credentials_set_secrets from ldb"); if (!tmp_ctx) { return NT_STATUS_NO_MEMORY; } /* Bleh, nasty recursion issues: We are setting a machine * account here, so we don't want the 'pending' flag around * any more */ cred->machine_account_pending = false; /* We have to do this, as the fallback in * cli_credentials_set_secrets is to run as anonymous, so the domain is wiped */ domain = cli_credentials_get_domain(cred); if (db_ctx) { TDB_DATA dbuf; keystr = talloc_asprintf(tmp_ctx, "%s/%s", SECRETS_MACHINE_LAST_CHANGE_TIME, domain); keystr_upper = strupper_talloc(tmp_ctx, keystr); status = dbwrap_fetch(db_ctx, tmp_ctx, string_tdb_data(keystr_upper), &dbuf); if (NT_STATUS_IS_OK(status) && dbuf.dsize == 4) { secrets_tdb_lct = IVAL(dbuf.dptr,0); } keystr = talloc_asprintf(tmp_ctx, "%s/%s", SECRETS_MACHINE_PASSWORD, domain); keystr_upper = strupper_talloc(tmp_ctx, keystr); status = dbwrap_fetch(db_ctx, tmp_ctx, string_tdb_data(keystr_upper), &dbuf); if (NT_STATUS_IS_OK(status)) { secrets_tdb_password = (char *)dbuf.dptr; } keystr = talloc_asprintf(tmp_ctx, "%s/%s", SECRETS_MACHINE_PASSWORD_PREV, domain); keystr_upper = strupper_talloc(tmp_ctx, keystr); status = dbwrap_fetch(db_ctx, tmp_ctx, string_tdb_data(keystr_upper), &dbuf); if (NT_STATUS_IS_OK(status)) { secrets_tdb_old_password = (char *)dbuf.dptr; } keystr = talloc_asprintf(tmp_ctx, "%s/%s", SECRETS_MACHINE_SEC_CHANNEL_TYPE, domain); keystr_upper = strupper_talloc(tmp_ctx, keystr); status = dbwrap_fetch(db_ctx, tmp_ctx, string_tdb_data(keystr_upper), &dbuf); if (NT_STATUS_IS_OK(status) && dbuf.dsize == 4) { secrets_tdb_secure_channel_type = IVAL(dbuf.dptr,0); } } filter = talloc_asprintf(cred, SECRETS_PRIMARY_DOMAIN_FILTER, domain); status = cli_credentials_set_secrets_lct(cred, lp_ctx, NULL, SECRETS_PRIMARY_DOMAIN_DN, filter, secrets_tdb_lct, secrets_tdb_password, &error_string); if (secrets_tdb_password == NULL) { secrets_tdb_password_more_recent = false; } else if (NT_STATUS_EQUAL(NT_STATUS_CANT_ACCESS_DOMAIN_INFO, status) || NT_STATUS_EQUAL(NT_STATUS_NOT_FOUND, status)) { secrets_tdb_password_more_recent = true; } else if (secrets_tdb_lct > cli_credentials_get_password_last_changed_time(cred)) { secrets_tdb_password_more_recent = true; } else if (secrets_tdb_lct == cli_credentials_get_password_last_changed_time(cred)) { secrets_tdb_password_more_recent = strcmp(secrets_tdb_password, cli_credentials_get_password(cred)) != 0; } else { secrets_tdb_password_more_recent = false; } if (secrets_tdb_password_more_recent) { char *machine_account = talloc_asprintf(tmp_ctx, "%s$", lpcfg_netbios_name(lp_ctx)); cli_credentials_set_password(cred, secrets_tdb_password, CRED_SPECIFIED); cli_credentials_set_old_password(cred, secrets_tdb_old_password, CRED_SPECIFIED); cli_credentials_set_domain(cred, domain, CRED_SPECIFIED); if (strequal(domain, lpcfg_workgroup(lp_ctx))) { cli_credentials_set_realm(cred, lpcfg_realm(lp_ctx), CRED_SPECIFIED); } cli_credentials_set_username(cred, machine_account, CRED_SPECIFIED); cli_credentials_set_password_last_changed_time(cred, secrets_tdb_lct); cli_credentials_set_secure_channel_type(cred, secrets_tdb_secure_channel_type); status = NT_STATUS_OK; } else if (!NT_STATUS_IS_OK(status)) { if (db_ctx) { error_string = talloc_asprintf(cred, "Failed to fetch machine account password for %s from both " "secrets.ldb (%s) and from %s", domain, error_string == NULL ? "error" : error_string, dbwrap_name(db_ctx)); } else { char *secrets_tdb_path; secrets_tdb_path = lpcfg_private_db_path(tmp_ctx, lp_ctx, "secrets"); if (secrets_tdb_path == NULL) { return NT_STATUS_NO_MEMORY; } error_string = talloc_asprintf(cred, "Failed to fetch machine account password from " "secrets.ldb: %s and failed to open %s", error_string == NULL ? "error" : error_string, secrets_tdb_path); } DEBUG(1, ("Could not find machine account in secrets database: %s: %s\n", error_string == NULL ? "error" : error_string, nt_errstr(status))); /* set anonymous as the fallback, if the machine account won't work */ cli_credentials_set_anonymous(cred); } TALLOC_FREE(tmp_ctx); return status; }
static ADS_STATUS ads_guess_target(ADS_STRUCT *ads, char **service, char **hostname, char **principal) { ADS_STATUS status = ADS_ERROR(LDAP_NO_MEMORY); char *princ = NULL; TALLOC_CTX *frame; char *server = NULL; char *realm = NULL; int rc; frame = talloc_stackframe(); if (frame == NULL) { return ADS_ERROR(LDAP_NO_MEMORY); } if (ads->server.realm && ads->server.ldap_server) { server = strlower_talloc(frame, ads->server.ldap_server); if (server == NULL) { goto out; } realm = strupper_talloc(frame, ads->server.realm); if (realm == NULL) { goto out; } /* * If we got a name which is bigger than a NetBIOS name, * but isn't a FQDN, create one. */ if (strlen(server) > 15 && strstr(server, ".") == NULL) { char *dnsdomain; dnsdomain = strlower_talloc(frame, ads->server.realm); if (dnsdomain == NULL) { goto out; } server = talloc_asprintf(frame, "%s.%s", server, dnsdomain); if (server == NULL) { goto out; } } } else if (ads->config.realm && ads->config.ldap_server_name) { server = strlower_talloc(frame, ads->config.ldap_server_name); if (server == NULL) { goto out; } realm = strupper_talloc(frame, ads->config.realm); if (realm == NULL) { goto out; } /* * If we got a name which is bigger than a NetBIOS name, * but isn't a FQDN, create one. */ if (strlen(server) > 15 && strstr(server, ".") == NULL) { char *dnsdomain; dnsdomain = strlower_talloc(frame, ads->server.realm); if (dnsdomain == NULL) { goto out; } server = talloc_asprintf(frame, "%s.%s", server, dnsdomain); if (server == NULL) { goto out; } } } if (server == NULL || realm == NULL) { goto out; } *service = SMB_STRDUP("ldap"); if (*service == NULL) { status = ADS_ERROR(LDAP_PARAM_ERROR); goto out; } *hostname = SMB_STRDUP(server); if (*hostname == NULL) { SAFE_FREE(*service); status = ADS_ERROR(LDAP_PARAM_ERROR); goto out; } rc = asprintf(&princ, "ldap/%s@%s", server, realm); if (rc == -1 || princ == NULL) { SAFE_FREE(*service); SAFE_FREE(*hostname); status = ADS_ERROR(LDAP_PARAM_ERROR); goto out; } *principal = princ; status = ADS_SUCCESS; out: TALLOC_FREE(frame); return status; }
static int smb_krb5_create_salt_principal(TALLOC_CTX *mem_ctx, const char *samAccountName, const char *realm, const char **salt_principal, const char **error_string) { char *machine_username; bool is_machine_account = false; char *upper_realm; TALLOC_CTX *tmp_ctx; int rc = -1; if (samAccountName == NULL) { *error_string = "Cannot determine salt principal, no " "saltPrincipal or samAccountName specified"; return rc; } if (realm == NULL) { *error_string = "Cannot make principal without a realm"; return rc; } tmp_ctx = talloc_new(mem_ctx); if (tmp_ctx == NULL) { *error_string = "Cannot allocate talloc context"; return rc; } upper_realm = strupper_talloc(tmp_ctx, realm); if (upper_realm == NULL) { *error_string = "Cannot allocate to upper case realm"; goto out; } machine_username = strlower_talloc(tmp_ctx, samAccountName); if (!machine_username) { *error_string = "Cannot duplicate samAccountName"; goto out; } if (machine_username[strlen(machine_username) - 1] == '$') { machine_username[strlen(machine_username) - 1] = '\0'; is_machine_account = true; } if (is_machine_account) { char *lower_realm; lower_realm = strlower_talloc(tmp_ctx, realm); if (lower_realm == NULL) { *error_string = "Cannot allocate to lower case realm"; goto out; } *salt_principal = talloc_asprintf(mem_ctx, "host/%s.%s@%s", machine_username, lower_realm, upper_realm); } else { *salt_principal = talloc_asprintf(mem_ctx, "%s@%s", machine_username, upper_realm); } if (*salt_principal == NULL) { *error_string = "Cannot create salt principal"; goto out; } rc = 0; out: talloc_free(tmp_ctx); return rc; }
static bool test_plaintext(enum ntlm_break break_which) { NTSTATUS nt_status; uint32 flags = 0; DATA_BLOB nt_response = data_blob_null; DATA_BLOB lm_response = data_blob_null; char *password; smb_ucs2_t *nt_response_ucs2; size_t converted_size; uchar user_session_key[16]; uchar lm_key[16]; static const uchar zeros[8] = { 0, }; DATA_BLOB chall = data_blob(zeros, sizeof(zeros)); char *error_string; ZERO_STRUCT(user_session_key); flags |= WBFLAG_PAM_LMKEY; flags |= WBFLAG_PAM_USER_SESSION_KEY; if (!push_ucs2_talloc(talloc_tos(), &nt_response_ucs2, opt_password, &converted_size)) { DEBUG(0, ("push_ucs2_talloc failed!\n")); exit(1); } nt_response.data = (unsigned char *)nt_response_ucs2; nt_response.length = strlen_w(nt_response_ucs2)*sizeof(smb_ucs2_t); if ((password = strupper_talloc(talloc_tos(), opt_password)) == NULL) { DEBUG(0, ("strupper_talloc() failed!\n")); exit(1); } if (!convert_string_talloc(talloc_tos(), CH_UNIX, CH_DOS, password, strlen(password)+1, &lm_response.data, &lm_response.length, True)) { DEBUG(0, ("convert_string_talloc failed!\n")); exit(1); } TALLOC_FREE(password); switch (break_which) { case BREAK_NONE: break; case BREAK_LM: lm_response.data[0]++; break; case BREAK_NT: nt_response.data[0]++; break; case NO_LM: TALLOC_FREE(lm_response.data); lm_response.length = 0; break; case NO_NT: TALLOC_FREE(nt_response.data); nt_response.length = 0; break; } nt_status = contact_winbind_auth_crap(opt_username, opt_domain, opt_workstation, &chall, &lm_response, &nt_response, flags, lm_key, user_session_key, &error_string, NULL); TALLOC_FREE(nt_response.data); TALLOC_FREE(lm_response.data); data_blob_free(&chall); if (!NT_STATUS_IS_OK(nt_status)) { d_printf("%s (0x%x)\n", error_string, NT_STATUS_V(nt_status)); SAFE_FREE(error_string); return break_which == BREAK_NT; } return break_which != BREAK_NT; }
static bool process_one(struct loadparm_context *lp_ctx, struct tevent_context *ev, struct interface *ifaces, const char *name, int nbt_port) { TALLOC_CTX *tmp_ctx = talloc_new(NULL); enum nbt_name_type node_type = NBT_NAME_CLIENT; char *node_name, *p; struct socket_address *all_zero_addr; struct nbt_name_socket *nbtsock; NTSTATUS status = NT_STATUS_OK; bool ret = true; if (!options.case_sensitive) { name = strupper_talloc(tmp_ctx, name); } if (options.find_master) { node_type = NBT_NAME_MASTER; if (*name == '-' || *name == '_') { name = "\01\02__MSBROWSE__\02"; node_type = NBT_NAME_MS; } } p = strchr(name, '#'); if (p) { node_name = talloc_strndup(tmp_ctx, name, PTR_DIFF(p,name)); node_type = (enum nbt_name_type)strtol(p+1, NULL, 16); } else { node_name = talloc_strdup(tmp_ctx, name); } nbtsock = nbt_name_socket_init(tmp_ctx, ev, lp_iconv_convenience(lp_ctx)); if (options.root_port) { all_zero_addr = socket_address_from_strings(tmp_ctx, nbtsock->sock->backend_name, "0.0.0.0", NBT_NAME_SERVICE_PORT); if (!all_zero_addr) { talloc_free(tmp_ctx); return false; } status = socket_listen(nbtsock->sock, all_zero_addr, 0, 0); if (!NT_STATUS_IS_OK(status)) { printf("Failed to bind to local port 137 - %s\n", nt_errstr(status)); talloc_free(tmp_ctx); return false; } } if (options.lookup_by_ip) { ret = do_node_status(nbtsock, name, nbt_port); talloc_free(tmp_ctx); return ret; } if (options.broadcast_address) { status = do_node_query(nbtsock, options.broadcast_address, nbt_port, node_name, node_type, true); } else if (options.unicast_address) { status = do_node_query(nbtsock, options.unicast_address, nbt_port, node_name, node_type, false); } else { int i, num_interfaces; num_interfaces = iface_count(ifaces); for (i=0;i<num_interfaces;i++) { const char *bcast = iface_n_bcast(ifaces, i); if (bcast == NULL) continue; status = do_node_query(nbtsock, bcast, nbt_port, node_name, node_type, true); if (NT_STATUS_IS_OK(status)) break; } } if (!NT_STATUS_IS_OK(status)) { printf("Lookup failed - %s\n", nt_errstr(status)); ret = false; } talloc_free(tmp_ctx); return ret; }
static krb5_error_code salt_principal_from_msg(TALLOC_CTX *parent_ctx, struct ldb_message *msg, struct smb_krb5_context *smb_krb5_context, krb5_principal *salt_princ, const char **error_string) { const char *salt_principal = ldb_msg_find_attr_as_string(msg, "saltPrincipal", NULL); const char *samAccountName = ldb_msg_find_attr_as_string(msg, "samAccountName", NULL); const char *realm = ldb_msg_find_attr_as_string(msg, "realm", NULL); if (salt_principal) { return parse_principal(parent_ctx, salt_principal, smb_krb5_context, salt_princ, error_string); } else if (samAccountName) { krb5_error_code ret; char *machine_username; char *salt_body; char *lower_realm; char *upper_realm; TALLOC_CTX *tmp_ctx; struct principal_container *mem_ctx = talloc(parent_ctx, struct principal_container); if (!mem_ctx) { *error_string = "Cannot allocate mem_ctx"; return ENOMEM; } tmp_ctx = talloc_new(mem_ctx); if (!tmp_ctx) { talloc_free(mem_ctx); *error_string = "Cannot allocate tmp_ctx"; return ENOMEM; } if (!realm) { *error_string = "Cannot have a kerberos secret in secrets.ldb without a realm"; return EINVAL; } machine_username = talloc_strdup(tmp_ctx, samAccountName); if (!machine_username) { talloc_free(mem_ctx); *error_string = "Cannot duplicate samAccountName"; return ENOMEM; } if (machine_username[strlen(machine_username)-1] == '$') { machine_username[strlen(machine_username)-1] = '\0'; } lower_realm = strlower_talloc(tmp_ctx, realm); if (!lower_realm) { talloc_free(mem_ctx); *error_string = "Cannot allocate to lower case realm"; return ENOMEM; } upper_realm = strupper_talloc(tmp_ctx, realm); if (!upper_realm) { talloc_free(mem_ctx); *error_string = "Cannot allocate to upper case realm"; return ENOMEM; } salt_body = talloc_asprintf(tmp_ctx, "%s.%s", machine_username, lower_realm); talloc_free(lower_realm); talloc_free(machine_username); if (!salt_body) { talloc_free(mem_ctx); *error_string = "Cannot form salt principal body"; return ENOMEM; } ret = krb5_make_principal(smb_krb5_context->krb5_context, salt_princ, upper_realm, "host", salt_body, NULL); if (ret == 0) { /* This song-and-dance effectivly puts the principal * into talloc, so we can't loose it. */ mem_ctx->smb_krb5_context = talloc_reference(mem_ctx, smb_krb5_context); mem_ctx->principal = *salt_princ; talloc_set_destructor(mem_ctx, free_principal); } else { (*error_string) = smb_get_krb5_error_message(smb_krb5_context->krb5_context, ret, parent_ctx); } talloc_free(tmp_ctx); return ret; } else {
static krb5_error_code principals_from_msg(TALLOC_CTX *parent_ctx, struct ldb_message *msg, struct smb_krb5_context *smb_krb5_context, struct principal_container ***principals_out, const char **error_string) { unsigned int i; krb5_error_code ret; char *upper_realm; const char *realm = ldb_msg_find_attr_as_string(msg, "realm", NULL); const char *samAccountName = ldb_msg_find_attr_as_string(msg, "samAccountName", NULL); struct ldb_message_element *spn_el = ldb_msg_find_element(msg, "servicePrincipalName"); TALLOC_CTX *tmp_ctx; struct principal_container **principals; tmp_ctx = talloc_new(parent_ctx); if (!tmp_ctx) { *error_string = "Cannot allocate tmp_ctx"; return ENOMEM; } if (!realm) { *error_string = "Cannot have a kerberos secret in secrets.ldb without a realm"; return EINVAL; } upper_realm = strupper_talloc(tmp_ctx, realm); if (!upper_realm) { talloc_free(tmp_ctx); *error_string = "Cannot allocate full upper case realm"; return ENOMEM; } principals = talloc_array(tmp_ctx, struct principal_container *, spn_el ? (spn_el->num_values + 2) : 2); spn_el = ldb_msg_find_element(msg, "servicePrincipalName"); for (i=0; spn_el && i < spn_el->num_values; i++) { principals[i] = talloc(principals, struct principal_container); if (!principals[i]) { talloc_free(tmp_ctx); *error_string = "Cannot allocate mem_ctx"; return ENOMEM; } principals[i]->smb_krb5_context = talloc_reference(principals[i], smb_krb5_context); principals[i]->string_form = talloc_asprintf(principals[i], "%*.*s@%s", (int)spn_el->values[i].length, (int)spn_el->values[i].length, (const char *)spn_el->values[i].data, upper_realm); if (!principals[i]->string_form) { talloc_free(tmp_ctx); *error_string = "Cannot allocate full samAccountName"; return ENOMEM; } ret = krb5_parse_name(smb_krb5_context->krb5_context, principals[i]->string_form, &principals[i]->principal); if (ret) { talloc_free(tmp_ctx); (*error_string) = smb_get_krb5_error_message(smb_krb5_context->krb5_context, ret, parent_ctx); return ret; } /* This song-and-dance effectivly puts the principal * into talloc, so we can't loose it. */ talloc_set_destructor(principals[i], free_principal); } if (samAccountName) { principals[i] = talloc(principals, struct principal_container); if (!principals[i]) { talloc_free(tmp_ctx); *error_string = "Cannot allocate mem_ctx"; return ENOMEM; } principals[i]->smb_krb5_context = talloc_reference(principals[i], smb_krb5_context); principals[i]->string_form = talloc_asprintf(parent_ctx, "%s@%s", samAccountName, upper_realm); if (!principals[i]->string_form) { talloc_free(tmp_ctx); *error_string = "Cannot allocate full samAccountName"; return ENOMEM; } ret = krb5_make_principal(smb_krb5_context->krb5_context, &principals[i]->principal, upper_realm, samAccountName, NULL); if (ret) { talloc_free(tmp_ctx); (*error_string) = smb_get_krb5_error_message(smb_krb5_context->krb5_context, ret, parent_ctx); return ret; } /* This song-and-dance effectivly puts the principal * into talloc, so we can't loose it. */ talloc_set_destructor(principals[i], free_principal); i++; } principals[i] = NULL; *principals_out = talloc_steal(parent_ctx, principals); talloc_free(tmp_ctx); return ret; }
static krb5_error_code salt_principal(TALLOC_CTX *parent_ctx, const char *samAccountName, const char *realm, const char *saltPrincipal, krb5_context context, krb5_principal *salt_princ, const char **error_string) { krb5_error_code ret; char *machine_username; char *salt_body; char *lower_realm; char *upper_realm; TALLOC_CTX *tmp_ctx; if (saltPrincipal) { ret = krb5_parse_name(context, saltPrincipal, salt_princ); if (ret) { *error_string = smb_get_krb5_error_message( context, ret, parent_ctx); } return ret; } if (!samAccountName) { (*error_string) = "Cannot determine salt principal, no " "saltPrincipal or samAccountName specified"; return EINVAL; } if (!realm) { *error_string = "Cannot make principal without a realm"; return EINVAL; } tmp_ctx = talloc_new(parent_ctx); if (!tmp_ctx) { *error_string = "Cannot allocate tmp_ctx"; return ENOMEM; } machine_username = talloc_strdup(tmp_ctx, samAccountName); if (!machine_username) { *error_string = "Cannot duplicate samAccountName"; talloc_free(tmp_ctx); return ENOMEM; } if (machine_username[strlen(machine_username)-1] == '$') { machine_username[strlen(machine_username)-1] = '\0'; } lower_realm = strlower_talloc(tmp_ctx, realm); if (!lower_realm) { *error_string = "Cannot allocate to lower case realm"; talloc_free(tmp_ctx); return ENOMEM; } upper_realm = strupper_talloc(tmp_ctx, realm); if (!upper_realm) { *error_string = "Cannot allocate to upper case realm"; talloc_free(tmp_ctx); return ENOMEM; } salt_body = talloc_asprintf(tmp_ctx, "%s.%s", machine_username, lower_realm); if (!salt_body) { *error_string = "Cannot form salt principal body"; talloc_free(tmp_ctx); return ENOMEM; } ret = smb_krb5_make_principal(context, salt_princ, upper_realm, "host", salt_body, NULL); if (ret) { *error_string = smb_get_krb5_error_message(context, ret, parent_ctx); } talloc_free(tmp_ctx); return ret; }
static krb5_error_code principals_from_list(TALLOC_CTX *parent_ctx, const char *samAccountName, const char *realm, const char **SPNs, int num_SPNs, krb5_context context, krb5_principal **principals_out, const char **error_string) { unsigned int i; krb5_error_code ret; char *upper_realm; TALLOC_CTX *tmp_ctx; krb5_principal *principals = NULL; tmp_ctx = talloc_new(parent_ctx); if (!tmp_ctx) { *error_string = "Cannot allocate tmp_ctx"; return ENOMEM; } if (!realm) { *error_string = "Cannot make principal without a realm"; ret = EINVAL; goto done; } upper_realm = strupper_talloc(tmp_ctx, realm); if (!upper_realm) { *error_string = "Cannot allocate full upper case realm"; ret = ENOMEM; goto done; } principals = talloc_zero_array(tmp_ctx, krb5_principal, num_SPNs ? (num_SPNs + 2) : 2); for (i = 0; num_SPNs && i < num_SPNs; i++) { ret = krb5_parse_name(context, SPNs[i], &principals[i]); if (ret) { *error_string = smb_get_krb5_error_message(context, ret, parent_ctx); goto done; } } if (samAccountName) { ret = smb_krb5_make_principal(context, &principals[i], upper_realm, samAccountName, NULL); if (ret) { *error_string = smb_get_krb5_error_message(context, ret, parent_ctx); goto done; } } done: if (ret) { keytab_principals_free(context, principals); } else { *principals_out = talloc_steal(parent_ctx, principals); } talloc_free(tmp_ctx); return ret; }
/* Does both the NTLMv2 owfs of a user's password */ bool ntv2_owf_gen(const uint8_t owf[16], const char *user_in, const char *domain_in, uint8_t kr_buf[16]) { smb_ucs2_t *user; smb_ucs2_t *domain; size_t user_byte_len; size_t domain_byte_len; bool ret; HMACMD5Context ctx; TALLOC_CTX *mem_ctx = talloc_init("ntv2_owf_gen for %s\\%s", domain_in, user_in); if (!mem_ctx) { return false; } if (!user_in) { user_in = ""; } if (!domain_in) { domain_in = ""; } user_in = strupper_talloc(mem_ctx, user_in); if (user_in == NULL) { talloc_free(mem_ctx); return false; } ret = push_ucs2_talloc(mem_ctx, &user, user_in, &user_byte_len ); if (!ret) { DEBUG(0, ("push_uss2_talloc() for user failed)\n")); talloc_free(mem_ctx); return false; } ret = push_ucs2_talloc(mem_ctx, &domain, domain_in, &domain_byte_len); if (!ret) { DEBUG(0, ("push_ucs2_talloc() for domain failed\n")); talloc_free(mem_ctx); return false; } SMB_ASSERT(user_byte_len >= 2); SMB_ASSERT(domain_byte_len >= 2); /* We don't want null termination */ user_byte_len = user_byte_len - 2; domain_byte_len = domain_byte_len - 2; hmac_md5_init_limK_to_64(owf, 16, &ctx); hmac_md5_update((uint8_t *)user, user_byte_len, &ctx); hmac_md5_update((uint8_t *)domain, domain_byte_len, &ctx); hmac_md5_final(kr_buf, &ctx); #ifdef DEBUG_PASSWORD DEBUG(100, ("ntv2_owf_gen: user, domain, owfkey, kr\n")); dump_data(100, (uint8_t *)user, user_byte_len); dump_data(100, (uint8_t *)domain, domain_byte_len); dump_data(100, owf, 16); dump_data(100, kr_buf, 16); #endif talloc_free(mem_ctx); return true; }
NTSTATUS gp_create_gpo (struct gp_context *gp_ctx, const char *display_name, struct gp_object **ret) { struct GUID guid_struct; char *guid_str; char *name; struct security_descriptor *sd; TALLOC_CTX *mem_ctx; struct gp_object *gpo; NTSTATUS status; /* Create a forked memory context, as a base for everything here */ mem_ctx = talloc_new(gp_ctx); NT_STATUS_HAVE_NO_MEMORY(mem_ctx); /* Create the gpo struct to return later */ gpo = talloc(gp_ctx, struct gp_object); if (gpo == NULL) { TALLOC_FREE(mem_ctx); return NT_STATUS_NO_MEMORY; } /* Generate a GUID */ guid_struct = GUID_random(); guid_str = GUID_string2(mem_ctx, &guid_struct); if (guid_str == NULL) { TALLOC_FREE(mem_ctx); return NT_STATUS_NO_MEMORY; } name = strupper_talloc(mem_ctx, guid_str); if (name == NULL) { TALLOC_FREE(mem_ctx); return NT_STATUS_NO_MEMORY; } /* Prepare the GPO struct */ gpo->dn = NULL; gpo->name = name; gpo->flags = 0; gpo->version = 0; gpo->display_name = talloc_strdup(gpo, display_name); if (gpo->display_name == NULL) { TALLOC_FREE(mem_ctx); return NT_STATUS_NO_MEMORY; } gpo->file_sys_path = talloc_asprintf(gpo, "\\\\%s\\sysvol\\%s\\Policies\\%s", lpcfg_dnsdomain(gp_ctx->lp_ctx), lpcfg_dnsdomain(gp_ctx->lp_ctx), name); if (gpo->file_sys_path == NULL) { TALLOC_FREE(mem_ctx); return NT_STATUS_NO_MEMORY; } /* Create the GPT */ status = gp_create_gpt(gp_ctx, name, gpo->file_sys_path); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("Failed to create GPT\n")); talloc_free(mem_ctx); return status; } /* Create the LDAP GPO, including CN=User and CN=Machine */ status = gp_create_ldap_gpo(gp_ctx, gpo); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("Failed to create LDAP group policy object\n")); talloc_free(mem_ctx); return status; } /* Get the new security descriptor */ status = gp_get_gpo_info(gp_ctx, gpo->dn, &gpo); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("Failed to fetch LDAP group policy object\n")); talloc_free(mem_ctx); return status; } /* Create matching file and DS security descriptors */ status = gp_create_gpt_security_descriptor(mem_ctx, gpo->security_descriptor, &sd); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("Failed to convert ADS security descriptor to filesystem security descriptor\n")); talloc_free(mem_ctx); return status; } /* Set the security descriptor on the filesystem for this GPO */ status = gp_set_gpt_security_descriptor(gp_ctx, gpo, sd); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("Failed to set security descriptor (ACL) on the file system\n")); talloc_free(mem_ctx); return status; } talloc_free(mem_ctx); *ret = gpo; return NT_STATUS_OK; }
static bool torture_ldb_dn_extended(struct torture_context *torture) { TALLOC_CTX *mem_ctx = talloc_new(torture); struct ldb_context *ldb; struct ldb_dn *dn, *dn2; DATA_BLOB sid_blob = strhex_to_data_blob(mem_ctx, hex_sid); DATA_BLOB guid_blob = strhex_to_data_blob(mem_ctx, hex_guid); const char *dn_str = "cn=admin,cn=users,dc=samba,dc=org"; torture_assert(torture, ldb = ldb_init(mem_ctx, torture->ev), "Failed to init ldb"); torture_assert_int_equal(torture, ldb_register_samba_handlers(ldb), 0, "Failed to register Samba handlers"); ldb_set_utf8_fns(ldb, NULL, wrap_casefold); /* Check behaviour of a normal DN */ torture_assert(torture, dn = ldb_dn_new(mem_ctx, ldb, dn_str), "Failed to create a 'normal' DN"); torture_assert(torture, ldb_dn_validate(dn), "Failed to validate 'normal' DN"); torture_assert(torture, ldb_dn_has_extended(dn) == false, "Should not find plain DN to be 'extended'"); torture_assert(torture, ldb_dn_get_extended_component(dn, "SID") == NULL, "Should not find an SID on plain DN"); torture_assert(torture, ldb_dn_get_extended_component(dn, "GUID") == NULL, "Should not find an GUID on plain DN"); torture_assert(torture, ldb_dn_get_extended_component(dn, "WKGUID") == NULL, "Should not find an WKGUID on plain DN"); /* Now make an extended DN */ torture_assert(torture, dn = ldb_dn_new_fmt(mem_ctx, ldb, "<GUID=%s>;<SID=%s>;%s", guid, sid, dn_str), "Failed to create an 'extended' DN"); torture_assert(torture, dn2 = ldb_dn_copy(mem_ctx, dn), "Failed to copy the 'extended' DN"); talloc_free(dn); dn = dn2; torture_assert(torture, ldb_dn_validate(dn), "Failed to validate 'extended' DN"); torture_assert(torture, ldb_dn_has_extended(dn) == true, "Should find extended DN to be 'extended'"); torture_assert(torture, ldb_dn_get_extended_component(dn, "SID") != NULL, "Should find an SID on extended DN"); torture_assert(torture, ldb_dn_get_extended_component(dn, "GUID") != NULL, "Should find an GUID on extended DN"); torture_assert_data_blob_equal(torture, *ldb_dn_get_extended_component(dn, "SID"), sid_blob, "Extended DN SID incorect"); torture_assert_data_blob_equal(torture, *ldb_dn_get_extended_component(dn, "GUID"), guid_blob, "Extended DN GUID incorect"); torture_assert_str_equal(torture, ldb_dn_get_linearized(dn), dn_str, "linearized DN incorrect"); torture_assert_str_equal(torture, ldb_dn_get_casefold(dn), strupper_talloc(mem_ctx, dn_str), "casefolded DN incorrect"); torture_assert_str_equal(torture, ldb_dn_get_component_name(dn, 0), "cn", "componet zero incorrect"); torture_assert_data_blob_equal(torture, *ldb_dn_get_component_val(dn, 0), data_blob_string_const("admin"), "componet zero incorrect"); torture_assert_str_equal(torture, ldb_dn_get_extended_linearized(mem_ctx, dn, 1), talloc_asprintf(mem_ctx, "<GUID=%s>;<SID=%s>;%s", guid, sid, dn_str), "Clear extended linearized DN incorrect"); torture_assert_str_equal(torture, ldb_dn_get_extended_linearized(mem_ctx, dn, 0), talloc_asprintf(mem_ctx, "<GUID=%s>;<SID=%s>;%s", hex_guid, hex_sid, dn_str), "HEX extended linearized DN incorrect"); torture_assert(torture, ldb_dn_remove_child_components(dn, 1) == true, "Failed to remove DN child"); torture_assert(torture, ldb_dn_has_extended(dn) == false, "Extended DN flag should be cleared after child element removal"); torture_assert(torture, ldb_dn_get_extended_component(dn, "SID") == NULL, "Should not find an SID on DN"); torture_assert(torture, ldb_dn_get_extended_component(dn, "GUID") == NULL, "Should not find an GUID on DN"); /* TODO: test setting these in the other order, and ensure it still comes out 'GUID first' */ torture_assert_int_equal(torture, ldb_dn_set_extended_component(dn, "GUID", &guid_blob), 0, "Failed to set a GUID on DN"); torture_assert_int_equal(torture, ldb_dn_set_extended_component(dn, "SID", &sid_blob), 0, "Failed to set a SID on DN"); torture_assert_data_blob_equal(torture, *ldb_dn_get_extended_component(dn, "SID"), sid_blob, "Extended DN SID incorect"); torture_assert_data_blob_equal(torture, *ldb_dn_get_extended_component(dn, "GUID"), guid_blob, "Extended DN GUID incorect"); torture_assert_str_equal(torture, ldb_dn_get_linearized(dn), "cn=users,dc=samba,dc=org", "linearized DN incorrect"); torture_assert_str_equal(torture, ldb_dn_get_extended_linearized(mem_ctx, dn, 1), talloc_asprintf(mem_ctx, "<GUID=%s>;<SID=%s>;%s", guid, sid, "cn=users,dc=samba,dc=org"), "Clear extended linearized DN incorrect"); torture_assert_str_equal(torture, ldb_dn_get_extended_linearized(mem_ctx, dn, 0), talloc_asprintf(mem_ctx, "<GUID=%s>;<SID=%s>;%s", hex_guid, hex_sid, "cn=users,dc=samba,dc=org"), "HEX extended linearized DN incorrect"); /* Now check a 'just GUID' DN (clear format) */ torture_assert(torture, dn = ldb_dn_new_fmt(mem_ctx, ldb, "<GUID=%s>", guid), "Failed to create an 'extended' DN"); torture_assert(torture, ldb_dn_validate(dn), "Failed to validate 'extended' DN"); torture_assert(torture, ldb_dn_has_extended(dn) == true, "Should find extended DN to be 'extended'"); torture_assert(torture, ldb_dn_get_extended_component(dn, "SID") == NULL, "Should not find an SID on this DN"); torture_assert_int_equal(torture, ldb_dn_get_comp_num(dn), 0, "Should not find an 'normal' componet on this DN"); torture_assert(torture, ldb_dn_get_extended_component(dn, "GUID") != NULL, "Should find an GUID on this DN"); torture_assert_data_blob_equal(torture, *ldb_dn_get_extended_component(dn, "GUID"), guid_blob, "Extended DN GUID incorect"); torture_assert_str_equal(torture, ldb_dn_get_linearized(dn), "", "linearized DN incorrect"); torture_assert_str_equal(torture, ldb_dn_get_extended_linearized(mem_ctx, dn, 1), talloc_asprintf(mem_ctx, "<GUID=%s>", guid), "Clear extended linearized DN incorrect"); torture_assert_str_equal(torture, ldb_dn_get_extended_linearized(mem_ctx, dn, 0), talloc_asprintf(mem_ctx, "<GUID=%s>", hex_guid), "HEX extended linearized DN incorrect"); /* Now check a 'just GUID' DN (HEX format) */ torture_assert(torture, dn = ldb_dn_new_fmt(mem_ctx, ldb, "<GUID=%s>", hex_guid), "Failed to create an 'extended' DN"); torture_assert(torture, ldb_dn_validate(dn), "Failed to validate 'extended' DN"); torture_assert(torture, ldb_dn_has_extended(dn) == true, "Should find extended DN to be 'extended'"); torture_assert(torture, ldb_dn_get_extended_component(dn, "SID") == NULL, "Should not find an SID on this DN"); torture_assert(torture, ldb_dn_get_extended_component(dn, "GUID") != NULL, "Should find an GUID on this DN"); torture_assert_data_blob_equal(torture, *ldb_dn_get_extended_component(dn, "GUID"), guid_blob, "Extended DN GUID incorect"); torture_assert_str_equal(torture, ldb_dn_get_linearized(dn), "", "linearized DN incorrect"); /* Now check a 'just SID' DN (clear format) */ torture_assert(torture, dn = ldb_dn_new_fmt(mem_ctx, ldb, "<SID=%s>", sid), "Failed to create an 'extended' DN"); torture_assert(torture, ldb_dn_validate(dn), "Failed to validate 'extended' DN"); torture_assert(torture, ldb_dn_has_extended(dn) == true, "Should find extended DN to be 'extended'"); torture_assert(torture, ldb_dn_get_extended_component(dn, "GUID") == NULL, "Should not find an SID on this DN"); torture_assert(torture, ldb_dn_get_extended_component(dn, "SID") != NULL, "Should find an SID on this DN"); torture_assert_data_blob_equal(torture, *ldb_dn_get_extended_component(dn, "SID"), sid_blob, "Extended DN SID incorect"); torture_assert_str_equal(torture, ldb_dn_get_linearized(dn), "", "linearized DN incorrect"); torture_assert_str_equal(torture, ldb_dn_get_extended_linearized(mem_ctx, dn, 1), talloc_asprintf(mem_ctx, "<SID=%s>", sid), "Clear extended linearized DN incorrect"); torture_assert_str_equal(torture, ldb_dn_get_extended_linearized(mem_ctx, dn, 0), talloc_asprintf(mem_ctx, "<SID=%s>", hex_sid), "HEX extended linearized DN incorrect"); /* Now check a 'just SID' DN (HEX format) */ torture_assert(torture, dn = ldb_dn_new_fmt(mem_ctx, ldb, "<SID=%s>", hex_sid), "Failed to create an 'extended' DN"); torture_assert(torture, ldb_dn_validate(dn), "Failed to validate 'extended' DN"); torture_assert(torture, ldb_dn_has_extended(dn) == true, "Should find extended DN to be 'extended'"); torture_assert(torture, ldb_dn_get_extended_component(dn, "GUID") == NULL, "Should not find an SID on this DN"); torture_assert(torture, ldb_dn_get_extended_component(dn, "SID") != NULL, "Should find an SID on this DN"); torture_assert_data_blob_equal(torture, *ldb_dn_get_extended_component(dn, "SID"), sid_blob, "Extended DN SID incorect"); torture_assert_str_equal(torture, ldb_dn_get_linearized(dn), "", "linearized DN incorrect"); talloc_free(mem_ctx); return true; }
static NTSTATUS schannel_fetch_session_key_tdb(struct tdb_wrap *tdb_sc, TALLOC_CTX *mem_ctx, const char *computer_name, struct netlogon_creds_CredentialState **pcreds) { NTSTATUS status; TDB_DATA value; enum ndr_err_code ndr_err; DATA_BLOB blob; struct netlogon_creds_CredentialState *creds = NULL; char *keystr = NULL; char *name_upper; *pcreds = NULL; name_upper = strupper_talloc(mem_ctx, computer_name); if (!name_upper) { return NT_STATUS_NO_MEMORY; } keystr = talloc_asprintf(mem_ctx, "%s/%s", SECRETS_SCHANNEL_STATE, name_upper); TALLOC_FREE(name_upper); if (!keystr) { return NT_STATUS_NO_MEMORY; } value = tdb_fetch_bystring(tdb_sc->tdb, keystr); if (!value.dptr) { DEBUG(10,("schannel_fetch_session_key_tdb: Failed to find entry with key %s\n", keystr )); status = NT_STATUS_OBJECT_NAME_NOT_FOUND; goto done; } creds = talloc_zero(mem_ctx, struct netlogon_creds_CredentialState); if (!creds) { status = NT_STATUS_NO_MEMORY; goto done; } blob = data_blob_const(value.dptr, value.dsize); ndr_err = ndr_pull_struct_blob(&blob, creds, creds, (ndr_pull_flags_fn_t)ndr_pull_netlogon_creds_CredentialState); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { status = ndr_map_error2ntstatus(ndr_err); goto done; } if (DEBUGLEVEL >= 10) { NDR_PRINT_DEBUG(netlogon_creds_CredentialState, creds); } DEBUG(3,("schannel_fetch_session_key_tdb: restored schannel info key %s\n", keystr)); status = NT_STATUS_OK; done: talloc_free(keystr); SAFE_FREE(value.dptr); if (!NT_STATUS_IS_OK(status)) { talloc_free(creds); return status; } *pcreds = creds; return NT_STATUS_OK; }