static NTSTATUS remote_op_init_server(struct dcesrv_context *dce_ctx, const struct dcesrv_endpoint_server *ep_server) { unsigned int i; char **ifaces = str_list_make(dce_ctx, lpcfg_parm_string(dce_ctx->lp_ctx, NULL, "dcerpc_remote", "interfaces"),NULL); if (!ifaces) { DEBUG(3,("remote_op_init_server: no interfaces configured\n")); return NT_STATUS_OK; } for (i=0;ifaces[i];i++) { NTSTATUS ret; struct dcesrv_interface iface; if (!ep_server->interface_by_name(&iface, ifaces[i])) { DEBUG(0,("remote_op_init_server: failed to find interface = '%s'\n", ifaces[i])); talloc_free(ifaces); return NT_STATUS_UNSUCCESSFUL; } ret = remote_register_one_iface(dce_ctx, &iface); if (!NT_STATUS_IS_OK(ret)) { DEBUG(0,("remote_op_init_server: failed to register interface = '%s'\n", ifaces[i])); talloc_free(ifaces); return ret; } } talloc_free(ifaces); return NT_STATUS_OK; }
/* refresh a WINS name registration */ static void nbtd_wins_refresh(struct event_context *ev, struct timed_event *te, struct timeval t, void *private_data) { struct nbtd_iface_name *iname = talloc_get_type(private_data, struct nbtd_iface_name); struct nbtd_interface *iface = iname->iface; struct nbt_name_refresh_wins io; struct composite_context *c; TALLOC_CTX *tmp_ctx = talloc_new(iname); /* setup a wins name refresh request */ io.in.name = iname->name; io.in.wins_servers = str_list_make(tmp_ctx, iname->wins_server, NULL); io.in.addresses = nbtd_address_list(iface, tmp_ctx); io.in.nb_flags = iname->nb_flags; io.in.ttl = iname->ttl; if (!io.in.addresses) { talloc_free(tmp_ctx); return; } c = nbt_name_refresh_wins_send(wins_socket(iface), &io); if (c == NULL) { talloc_free(tmp_ctx); return; } talloc_steal(c, io.in.addresses); c->async.fn = nbtd_wins_refresh_handler; c->async.private_data = iname; talloc_free(tmp_ctx); }
/** Set user socket options. **/ _PUBLIC_ void set_socket_options(int fd, const char *options) { const char **options_list = (const char **)str_list_make(NULL, options, " \t,"); int j; if (!options_list) return; for (j = 0; options_list[j]; j++) { const char *tok = options_list[j]; int ret=0,i; int value = 1; char *p; bool got_value = false; if ((p = strchr(tok,'='))) { *p = 0; value = atoi(p+1); got_value = true; } for (i=0;socket_options[i].name;i++) if (strequal(socket_options[i].name,tok)) break; if (!socket_options[i].name) { DEBUG(0,("Unknown socket option %s\n",tok)); continue; } switch (socket_options[i].opttype) { case OPT_BOOL: case OPT_INT: ret = setsockopt(fd,socket_options[i].level, socket_options[i].option,(char *)&value,sizeof(int)); break; case OPT_ON: if (got_value) DEBUG(0,("syntax error - %s does not take a value\n",tok)); { int on = socket_options[i].value; ret = setsockopt(fd,socket_options[i].level, socket_options[i].option,(char *)&on,sizeof(int)); } break; } if (ret != 0) DEBUG(0,("Failed to set socket option %s (Error %s)\n",tok, strerror(errno) )); } talloc_free(options_list); }
void web_set_lang(const char *lang_string) { char **lang_list, **count; struct pri_list *pl; int lang_num, i; /* build the lang list */ lang_list = str_list_make(lang_string, ", \t\r\n"); if (!lang_list) return; /* sort the list by priority */ lang_num = 0; count = lang_list; while (*count && **count) { count++; lang_num++; } pl = SMB_MALLOC_ARRAY(struct pri_list, lang_num); if (!pl) { return; } for (i = 0; i < lang_num; i++) { char *pri_code; if ((pri_code=strstr(lang_list[i], ";q="))) { *pri_code = '\0'; pri_code += 3; sscanf(pri_code, "%f", &(pl[i].pri)); } else { pl[i].pri = 1; } pl[i].string = SMB_STRDUP(lang_list[i]); } str_list_free(&lang_list); qsort(pl, lang_num, sizeof(struct pri_list), &qsort_cmp_list); /* it's not an error to not initialise - we just fall back to the default */ for (i = 0; i < lang_num; i++) { if (lang_tdb_init(pl[i].string)) break; } for (i = 0; i < lang_num; i++) { SAFE_FREE(pl[i].string); } SAFE_FREE(pl); return; }
static BOOL user_ok(const char *user, int snum) { char **valid, **invalid; BOOL ret; valid = invalid = NULL; ret = True; if (lp_invalid_users(snum)) { str_list_copy(&invalid, lp_invalid_users(snum)); if (invalid && str_list_substitute(invalid, "%S", lp_servicename(snum))) { if ( invalid && str_list_sub_basic(invalid, current_user_info.smb_name) ) { ret = !user_in_list(user, (const char **)invalid); } } } if (invalid) str_list_free (&invalid); if (ret && lp_valid_users(snum)) { str_list_copy(&valid, lp_valid_users(snum)); if ( valid && str_list_substitute(valid, "%S", lp_servicename(snum)) ) { if ( valid && str_list_sub_basic(valid, current_user_info.smb_name) ) { ret = user_in_list(user, (const char **)valid); } } } if (valid) str_list_free (&valid); if (ret && lp_onlyuser(snum)) { char **user_list = str_list_make (lp_username(snum), NULL); if (user_list && str_list_substitute(user_list, "%S", lp_servicename(snum))) { ret = user_in_list(user, (const char **)user_list); } if (user_list) str_list_free (&user_list); } return(ret); }
bool ads_parse_gp_ext(TALLOC_CTX *mem_ctx, const char *extension_raw, struct GP_EXT **gp_ext) { bool ret = false; struct GP_EXT *ext = NULL; char **ext_list = NULL; char **ext_strings = NULL; int i; if (!extension_raw) { goto parse_error; } DEBUG(20,("ads_parse_gp_ext: %s\n", extension_raw)); ext = talloc_zero(mem_ctx, struct GP_EXT); if (!ext) { goto parse_error; } ext_list = str_list_make(mem_ctx, extension_raw, "]"); if (!ext_list) { goto parse_error; } for (i = 0; ext_list[i] != NULL; i++) { /* no op */ } ext->num_exts = i; if (ext->num_exts) { ext->extensions = talloc_zero_array(mem_ctx, char *, ext->num_exts); ext->extensions_guid = talloc_zero_array(mem_ctx, char *, ext->num_exts); ext->snapins = talloc_zero_array(mem_ctx, char *, ext->num_exts); ext->snapins_guid = talloc_zero_array(mem_ctx, char *, ext->num_exts); }
/**************************************************************************** parse the debug levels from smb.conf. Example debug level string: 3 tdb:5 printdrivers:7 Note: the 1st param has no "name:" preceeding it. ****************************************************************************/ BOOL debug_parse_levels(const char *params_str) { char **params; /* Just in case */ debug_init(); if (AllowDebugChange == False) return True; params = str_list_make(params_str, NULL); if (debug_parse_params(params)) { debug_dump_status(5); str_list_free(¶ms); return True; } else { str_list_free(¶ms); return False; } }
NTSTATUS make_auth_context_subsystem(struct auth_context **auth_context) { char **auth_method_list = NULL; NTSTATUS nt_status; if (lp_auth_methods() && !str_list_copy(&auth_method_list, lp_auth_methods())) { return NT_STATUS_NO_MEMORY; } if (auth_method_list == NULL) { switch (lp_security()) { case SEC_DOMAIN: DEBUG(5,("Making default auth method list for security=domain\n")); auth_method_list = str_list_make("guest sam winbind:ntdomain", NULL); break; case SEC_SERVER: DEBUG(5,("Making default auth method list for security=server\n")); auth_method_list = str_list_make("guest sam smbserver", NULL); break; case SEC_USER: if (lp_encrypted_passwords()) { if ((lp_server_role() == ROLE_DOMAIN_PDC) || (lp_server_role() == ROLE_DOMAIN_BDC)) { DEBUG(5,("Making default auth method list for DC, security=user, encrypt passwords = yes\n")); auth_method_list = str_list_make("guest sam winbind:trustdomain", NULL); } else { DEBUG(5,("Making default auth method list for standalone security=user, encrypt passwords = yes\n")); auth_method_list = str_list_make("guest sam", NULL); } } else { DEBUG(5,("Making default auth method list for security=user, encrypt passwords = no\n")); auth_method_list = str_list_make("guest unix", NULL); } break; case SEC_SHARE: if (lp_encrypted_passwords()) { DEBUG(5,("Making default auth method list for security=share, encrypt passwords = yes\n")); auth_method_list = str_list_make("guest sam", NULL); } else { DEBUG(5,("Making default auth method list for security=share, encrypt passwords = no\n")); auth_method_list = str_list_make("guest unix", NULL); } break; case SEC_ADS: DEBUG(5,("Making default auth method list for security=ADS\n")); auth_method_list = str_list_make("guest sam winbind:ntdomain", NULL); break; default: DEBUG(5,("Unknown auth method!\n")); return NT_STATUS_UNSUCCESSFUL; } } else { DEBUG(5,("Using specified auth order\n")); } if (!NT_STATUS_IS_OK(nt_status = make_auth_context_text_list(auth_context, auth_method_list))) { str_list_free(&auth_method_list); return nt_status; } str_list_free(&auth_method_list); return nt_status; }
/* test operations against a WINS server */ static bool nbt_test_wins_name(struct torture_context *tctx, const char *address, struct nbt_name *name, uint16_t nb_flags, bool try_low_port) { struct nbt_name_register_wins io; struct nbt_name_register name_register; struct nbt_name_query query; struct nbt_name_refresh_wins refresh; struct nbt_name_release release; struct nbt_name_request *req; NTSTATUS status; struct nbt_name_socket *nbtsock = torture_init_nbt_socket(tctx); const char *myaddress; struct socket_address *socket_address; struct interface *ifaces; bool low_port = try_low_port; load_interfaces(tctx, lp_interfaces(tctx->lp_ctx), &ifaces); myaddress = talloc_strdup(tctx, iface_best_ip(ifaces, address)); socket_address = socket_address_from_strings(tctx, nbtsock->sock->backend_name, myaddress, lp_nbt_port(tctx->lp_ctx)); torture_assert(tctx, socket_address != NULL, "Error getting address"); /* we do the listen here to ensure the WINS server receives the packets from the right IP */ status = socket_listen(nbtsock->sock, socket_address, 0, 0); talloc_free(socket_address); if (!NT_STATUS_IS_OK(status)) { low_port = false; socket_address = socket_address_from_strings(tctx, nbtsock->sock->backend_name, myaddress, 0); torture_assert(tctx, socket_address != NULL, "Error getting address"); status = socket_listen(nbtsock->sock, socket_address, 0, 0); talloc_free(socket_address); torture_assert_ntstatus_ok(tctx, status, "socket_listen for WINS failed"); } torture_comment(tctx, "Testing name registration to WINS with name %s at %s nb_flags=0x%x\n", nbt_name_string(tctx, name), myaddress, nb_flags); torture_comment(tctx, "release the name\n"); release.in.name = *name; release.in.dest_port = lp_nbt_port(tctx->lp_ctx); release.in.dest_addr = address; release.in.address = myaddress; release.in.nb_flags = nb_flags; release.in.broadcast = false; release.in.timeout = 3; release.in.retries = 0; status = nbt_name_release(nbtsock, tctx, &release); torture_assert_ntstatus_ok(tctx, status, talloc_asprintf(tctx, "Bad response from %s for name query", address)); CHECK_VALUE(tctx, release.out.rcode, 0); if (nb_flags & NBT_NM_GROUP) { /* ignore this for group names */ } else if (!low_port) { torture_comment(tctx, "no low port - skip: register the name with a wrong address\n"); } else { torture_comment(tctx, "register the name with a wrong address (makes the next request slow!)\n"); io.in.name = *name; io.in.wins_port = lp_nbt_port(tctx->lp_ctx); io.in.wins_servers = str_list_make(tctx, address, NULL); io.in.addresses = str_list_make(tctx, "127.64.64.1", NULL); io.in.nb_flags = nb_flags; io.in.ttl = 300000; status = nbt_name_register_wins(nbtsock, tctx, &io); if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) { torture_assert_ntstatus_ok(tctx, status, talloc_asprintf(tctx, "No response from %s for name register\n", address)); } torture_assert_ntstatus_ok(tctx, status, talloc_asprintf(tctx, "Bad response from %s for name register\n", address)); CHECK_STRING(tctx, io.out.wins_server, address); CHECK_VALUE(tctx, io.out.rcode, 0); torture_comment(tctx, "register the name correct address\n"); name_register.in.name = *name; name_register.in.dest_port = lp_nbt_port(tctx->lp_ctx); name_register.in.dest_addr = address; name_register.in.address = myaddress; name_register.in.nb_flags = nb_flags; name_register.in.register_demand= false; name_register.in.broadcast = false; name_register.in.multi_homed = true; name_register.in.ttl = 300000; name_register.in.timeout = 3; name_register.in.retries = 2; /* * test if the server ignores resent requests */ req = nbt_name_register_send(nbtsock, &name_register); while (true) { event_loop_once(nbtsock->event_ctx); if (req->state != NBT_REQUEST_WAIT) { break; } if (req->received_wack) { /* * if we received the wack response * we resend the request and the * server should ignore that * and not handle it as new request */ req->state = NBT_REQUEST_SEND; DLIST_ADD_END(nbtsock->send_queue, req, struct nbt_name_request *); EVENT_FD_WRITEABLE(nbtsock->fde); break; } } status = nbt_name_register_recv(req, tctx, &name_register); if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) { torture_assert_ntstatus_ok(tctx, status, talloc_asprintf(tctx, "No response from %s for name register\n", address)); } torture_assert_ntstatus_ok(tctx, status, talloc_asprintf(tctx, "Bad response from %s for name register\n", address)); CHECK_VALUE(tctx, name_register.out.rcode, 0); CHECK_STRING(tctx, name_register.out.reply_addr, myaddress); }
torture_assert_ntstatus_ok(tctx, status, talloc_asprintf(tctx, "No response from %s for name register\n", address)); } torture_assert_ntstatus_ok(tctx, status, talloc_asprintf(tctx, "Bad response from %s for name register\n", address)); CHECK_VALUE(tctx, name_register.out.rcode, 0); CHECK_STRING(tctx, name_register.out.reply_addr, myaddress); } torture_comment(tctx, "register the name correct address\n"); io.in.name = *name; io.in.wins_port = lp_nbt_port(tctx->lp_ctx); io.in.wins_servers = (const char **)str_list_make(tctx, address, NULL); io.in.addresses = (const char **)str_list_make(tctx, myaddress, NULL); io.in.nb_flags = nb_flags; io.in.ttl = 300000; status = nbt_name_register_wins(nbtsock, tctx, &io); torture_assert_ntstatus_ok(tctx, status, talloc_asprintf(tctx, "Bad response from %s for name register", address)); CHECK_STRING(tctx, io.out.wins_server, address); CHECK_VALUE(tctx, io.out.rcode, 0); if (name->type != NBT_NAME_MASTER && name->type != NBT_NAME_LOGON && name->type != NBT_NAME_BROWSER && (nb_flags & NBT_NM_GROUP)) { torture_comment(tctx, "Try to register as non-group\n");
/**************************************************************************** Do a specific test for a SAM_ACCOUNT being valid for this connection (ie not disabled, expired and the like). ****************************************************************************/ _PUBLIC_ NTSTATUS authsam_account_ok(TALLOC_CTX *mem_ctx, struct ldb_context *sam_ctx, uint32_t logon_parameters, struct ldb_dn *domain_dn, struct ldb_message *msg, const char *logon_workstation, const char *name_for_logs, bool allow_domain_trust, bool password_change) { uint16_t acct_flags; const char *workstation_list; NTTIME acct_expiry; NTTIME must_change_time; NTTIME now; DEBUG(4,("authsam_account_ok: Checking SMB password for user %s\n", name_for_logs)); acct_flags = samdb_result_acct_flags(sam_ctx, mem_ctx, msg, domain_dn); acct_expiry = samdb_result_account_expires(msg); /* Check for when we must change this password, taking the * userAccountControl flags into account */ must_change_time = samdb_result_force_password_change(sam_ctx, mem_ctx, domain_dn, msg); workstation_list = ldb_msg_find_attr_as_string(msg, "userWorkstations", NULL); /* Quit if the account was disabled. */ if (acct_flags & ACB_DISABLED) { DEBUG(2,("authsam_account_ok: Account for user '%s' was disabled.\n", name_for_logs)); return NT_STATUS_ACCOUNT_DISABLED; } /* Quit if the account was locked out. */ if (acct_flags & ACB_AUTOLOCK) { DEBUG(2,("authsam_account_ok: Account for user %s was locked out.\n", name_for_logs)); return NT_STATUS_ACCOUNT_LOCKED_OUT; } /* Test account expire time */ unix_to_nt_time(&now, time(NULL)); if (now > acct_expiry) { DEBUG(2,("authsam_account_ok: Account for user '%s' has expired.\n", name_for_logs)); DEBUG(3,("authsam_account_ok: Account expired at '%s'.\n", nt_time_string(mem_ctx, acct_expiry))); return NT_STATUS_ACCOUNT_EXPIRED; } /* check for immediate expiry "must change at next logon" (but not if this is a password change request) */ if ((must_change_time == 0) && !password_change) { DEBUG(2,("sam_account_ok: Account for user '%s' password must change!.\n", name_for_logs)); return NT_STATUS_PASSWORD_MUST_CHANGE; } /* check for expired password (but not if this is a password change request) */ if ((must_change_time < now) && !password_change) { DEBUG(2,("sam_account_ok: Account for user '%s' password expired!.\n", name_for_logs)); DEBUG(2,("sam_account_ok: Password expired at '%s' unix time.\n", nt_time_string(mem_ctx, must_change_time))); return NT_STATUS_PASSWORD_EXPIRED; } /* Test workstation. Workstation list is comma separated. */ if (logon_workstation && workstation_list && *workstation_list) { bool invalid_ws = true; int i; const char **workstations = (const char **)str_list_make(mem_ctx, workstation_list, ","); for (i = 0; workstations && workstations[i]; i++) { DEBUG(10,("sam_account_ok: checking for workstation match '%s' and '%s'\n", workstations[i], logon_workstation)); if (strequal(workstations[i], logon_workstation)) { invalid_ws = false; break; } } talloc_free(workstations); if (invalid_ws) { return NT_STATUS_INVALID_WORKSTATION; } } if (!logon_hours_ok(msg, name_for_logs)) { return NT_STATUS_INVALID_LOGON_HOURS; } if (!allow_domain_trust) { if (acct_flags & ACB_DOMTRUST) { DEBUG(2,("sam_account_ok: Domain trust account %s denied by server\n", name_for_logs)); return NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT; } } if (!(logon_parameters & MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT)) { if (acct_flags & ACB_SVRTRUST) { DEBUG(2,("sam_account_ok: Server trust account %s denied by server\n", name_for_logs)); return NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT; } } if (!(logon_parameters & MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT)) { /* TODO: this fails with current solaris client. We need to work with Gordon to work out why */ if (acct_flags & ACB_WSTRUST) { DEBUG(4,("sam_account_ok: Wksta trust account %s denied by server\n", name_for_logs)); return NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT; } } return NT_STATUS_OK; }
/* * Hook to allow handling of NTLM authentication for AD operation * without directly linking the s4 auth stack * * This ensures we use the source4 authentication stack, as well as * the authorization stack to create the user's token. This ensures * consistency between NTLM logins and NTLMSSP logins, as NTLMSSP is * handled by the hook above. */ static NTSTATUS make_auth4_context_s4(const struct auth_context *auth_context, TALLOC_CTX *mem_ctx, struct auth4_context **auth4_context) { NTSTATUS status; struct loadparm_context *lp_ctx; struct tevent_context *event_ctx; TALLOC_CTX *frame = talloc_stackframe(); struct imessaging_context *msg_ctx; struct server_id *server_id; lp_ctx = loadparm_init_s3(frame, loadparm_s3_helpers()); if (lp_ctx == NULL) { DEBUG(1, ("loadparm_init_s3 failed\n")); TALLOC_FREE(frame); return NT_STATUS_INVALID_SERVER_STATE; } event_ctx = s4_event_context_init(frame); if (event_ctx == NULL) { DEBUG(1, ("s4_event_context_init failed\n")); TALLOC_FREE(frame); return NT_STATUS_INVALID_SERVER_STATE; } server_id = new_server_id_task(frame); if (server_id == NULL) { DEBUG(1, ("new_server_id_task failed\n")); TALLOC_FREE(frame); return NT_STATUS_INVALID_SERVER_STATE; } msg_ctx = imessaging_init(frame, lp_ctx, *server_id, event_ctx, true); if (msg_ctx == NULL) { DEBUG(1, ("imessaging_init failed\n")); TALLOC_FREE(frame); return NT_STATUS_INVALID_SERVER_STATE; } talloc_reparent(frame, msg_ctx, server_id); /* Allow forcing a specific auth4 module */ if (!auth_context->forced_samba4_methods) { status = auth_context_create(mem_ctx, event_ctx, msg_ctx, lp_ctx, auth4_context); } else { const char * const *forced_auth_methods = (const char * const *)str_list_make(mem_ctx, auth_context->forced_samba4_methods, NULL); status = auth_context_create_methods(mem_ctx, forced_auth_methods, event_ctx, msg_ctx, lp_ctx, NULL, auth4_context); } if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("Failed to start auth server code: %s\n", nt_errstr(status))); TALLOC_FREE(frame); return status; } talloc_reparent(frame, *auth4_context, msg_ctx); talloc_reparent(frame, *auth4_context, event_ctx); talloc_reparent(frame, *auth4_context, lp_ctx); TALLOC_FREE(frame); return status; }