static struct winbindd_domain *add_trusted_domain(const char *domain_name, const char *alt_name, struct winbindd_methods *methods, const struct dom_sid *sid) { struct winbindd_domain *domain; const char *alternative_name = NULL; char *idmap_config_option; const char *param; const char **ignored_domains, **dom; int role = lp_server_role(); ignored_domains = lp_parm_string_list(-1, "winbind", "ignore domains", NULL); for (dom=ignored_domains; dom && *dom; dom++) { if (gen_fnmatch(*dom, domain_name) == 0) { DEBUG(2,("Ignoring domain '%s'\n", domain_name)); return NULL; } } /* use alt_name if available to allow DNS lookups */ if (alt_name && *alt_name) { alternative_name = alt_name; } /* We can't call domain_list() as this function is called from init_domain_list() and we'll get stuck in a loop. */ for (domain = _domain_list; domain; domain = domain->next) { if (strequal(domain_name, domain->name) || strequal(domain_name, domain->alt_name)) { break; } if (alternative_name && *alternative_name) { if (strequal(alternative_name, domain->name) || strequal(alternative_name, domain->alt_name)) { break; } } if (sid) { if (is_null_sid(sid)) { continue; } if (dom_sid_equal(sid, &domain->sid)) { break; } } } if (domain != NULL) { /* * We found a match on domain->name or * domain->alt_name. Possibly update the SID * if the stored SID was the NULL SID * and return the matching entry. */ if ((sid != NULL) && dom_sid_equal(&domain->sid, &global_sid_NULL)) { sid_copy( &domain->sid, sid ); } return domain; } /* Create new domain entry */ domain = talloc_zero(NULL, struct winbindd_domain); if (domain == NULL) { return NULL; } domain->children = talloc_zero_array(domain, struct winbindd_child, lp_winbind_max_domain_connections()); if (domain->children == NULL) { TALLOC_FREE(domain); return NULL; } domain->name = talloc_strdup(domain, domain_name); if (domain->name == NULL) { TALLOC_FREE(domain); return NULL; } if (alternative_name) { domain->alt_name = talloc_strdup(domain, alternative_name); if (domain->alt_name == NULL) { TALLOC_FREE(domain); return NULL; } } domain->methods = methods; domain->backend = NULL; domain->internal = is_internal_domain(sid); domain->sequence_number = DOM_SEQUENCE_NONE; domain->last_seq_check = 0; domain->initialized = False; domain->online = is_internal_domain(sid); domain->check_online_timeout = 0; domain->dc_probe_pid = (pid_t)-1; if (sid) { sid_copy(&domain->sid, sid); } /* Is this our primary domain ? */ if (strequal(domain_name, get_global_sam_name()) && (role != ROLE_DOMAIN_MEMBER)) { domain->primary = true; } else if (strequal(domain_name, lp_workgroup()) && (role == ROLE_DOMAIN_MEMBER)) { domain->primary = true; } if (domain->primary) { if (role == ROLE_ACTIVE_DIRECTORY_DC) { domain->active_directory = true; } if (lp_security() == SEC_ADS) { domain->active_directory = true; } } /* Link to domain list */ DLIST_ADD_END(_domain_list, domain, struct winbindd_domain *); wcache_tdc_add_domain( domain ); idmap_config_option = talloc_asprintf(talloc_tos(), "idmap config %s", domain->name); if (idmap_config_option == NULL) { DEBUG(0, ("talloc failed, not looking for idmap config\n")); goto done; } param = lp_parm_const_string(-1, idmap_config_option, "range", NULL); DEBUG(10, ("%s : range = %s\n", idmap_config_option, param ? param : "not defined")); if (param != NULL) { unsigned low_id, high_id; if (sscanf(param, "%u - %u", &low_id, &high_id) != 2) { DEBUG(1, ("invalid range syntax in %s: %s\n", idmap_config_option, param)); goto done; } if (low_id > high_id) { DEBUG(1, ("invalid range in %s: %s\n", idmap_config_option, param)); goto done; } domain->have_idmap_config = true; domain->id_range_low = low_id; domain->id_range_high = high_id; } done: setup_domain_child(domain); DEBUG(2,("Added domain %s %s %s\n", domain->name, domain->alt_name, &domain->sid?sid_string_dbg(&domain->sid):"")); return domain; }
/** * Initialize a domain structure * @param[in] mem_ctx memory context for the result * @param[in] domainname which domain is this for * @param[in] modulename which backend module * @param[in] check_range whether range checking should be done * @result The initialized structure */ static struct idmap_domain *idmap_init_domain(TALLOC_CTX *mem_ctx, const char *domainname, const char *modulename, bool check_range) { struct idmap_domain *result; NTSTATUS status; char *config_option = NULL; const char *range; unsigned low_id, high_id; result = talloc_zero(mem_ctx, struct idmap_domain); if (result == NULL) { DEBUG(0, ("talloc failed\n")); return NULL; } result->name = talloc_strdup(result, domainname); if (result->name == NULL) { DEBUG(0, ("talloc failed\n")); goto fail; } /* * Check whether the requested backend module exists and * load the methods. */ result->methods = get_methods(modulename); if (result->methods == NULL) { DEBUG(3, ("idmap backend %s not found\n", modulename)); status = smb_probe_module("idmap", modulename); if (!NT_STATUS_IS_OK(status)) { DEBUG(3, ("Could not probe idmap module %s\n", modulename)); goto fail; } result->methods = get_methods(modulename); } if (result->methods == NULL) { DEBUG(1, ("idmap backend %s not found\n", modulename)); goto fail; } /* * load ranges and read only information from the config */ config_option = talloc_asprintf(result, "idmap config %s", result->name); if (config_option == NULL) { DEBUG(0, ("Out of memory!\n")); goto fail; } result->read_only = lp_parm_bool(-1, config_option, "read only", false); range = lp_parm_const_string(-1, config_option, "range", NULL); talloc_free(config_option); if (range == NULL) { if (check_range) { DEBUG(1, ("idmap range not specified for domain %s\n", result->name)); goto fail; } } else if (sscanf(range, "%u - %u", &low_id, &high_id) != 2) { DEBUG(1, ("invalid range '%s' specified for domain " "'%s'\n", range, result->name)); if (check_range) { goto fail; } } else if (low_id > high_id) { DEBUG(1, ("Error: invalid idmap range detected: %u - %u\n", low_id, high_id)); if (check_range) { goto fail; } } result->low_id = low_id; result->high_id = high_id; status = result->methods->init(result); if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("idmap initialization returned %s\n", nt_errstr(status))); goto fail; } return result; fail: TALLOC_FREE(result); return NULL; }
static int python_connect(vfs_handle_struct *handle, const char *service, const char *user) { PyObject *pRet, *pArgs, *pValue, *pSysPath; const char *pysource_const, *pyarg; char pysource[PY_MAXPATH]; struct pyfuncs *pf; int i; pf = SMB_MALLOC_P(struct pyfuncs); if (!pf) { errno = ENOMEM; return -1; } handle->data = (void *)pf; handle->free_data = free_python_data; memset(pf, 0, sizeof(*pf)); pysource_const = lp_parm_const_string(SNUM(handle->conn), "vfs_python", "module_name", NULL); if (!pysource_const || pysource_const[0] == '\0') { DEBUG(1, ("vfs_python: module_name not set!\n")); errno = E_INTERNAL; return -1; } /* strlen doesn't count the trailing NULL, so even if they're the same length it's no good. */ if (strlen(pysource_const) >= sizeof(pysource)) { DEBUG(1, ("vfs_python: module_name too long!\n")); errno = ENOMEM; return -1; } /* Silly, but some implementations of dirname and basename modify their input parameters. */ strncpy((char *) &pysource, pysource_const, sizeof(pysource)); pyarg = dirname((char *) &pysource); /* If we have a path, add it to Python's search path. */ if (pyarg) { /* Note PySys_GetObject returns a borrowed reference */ pSysPath = PySys_GetObject("path"); if (!pSysPath) { errno = E_INTERNAL; return -1; } pArgs = PyString_FromString(pyarg); if (!pArgs) { errno = E_INTERNAL; return -1; } i = PyList_Append(pSysPath, pArgs); Py_DECREF(pArgs); if (i < 0) { errno = E_INTERNAL; return -1; } } /* Now actually include the module (by its basename). */ strncpy((char *) &pysource, pysource_const, sizeof(pysource)); pyarg = basename((char *) &pysource); if (!pyarg || pyarg[0] == '\0') { DEBUG(1, ("vfs_python: Invalid module_name!\n")); errno = E_INTERNAL; return -1; } pArgs = PyString_FromString(pyarg); pf->pModule = PyImport_Import(pArgs); Py_DECREF(pArgs); if (!pf->pModule) { DEBUG(1, ("vfs_python: Failed to load module '%s'. Make sure not to include a trailing '.py' or '.pyc' in your module path.\n", pysource_const)); PyErr_Print(); errno = E_INTERNAL; return -1; } #define VFS_PY_REQUIRED_MODULE_FUNC(_member, _name) \ pf->pFunc##_member = PyObject_GetAttrString(pf->pModule, _name); \ if (!pf->pFunc##_member || !PyCallable_Check(pf->pFunc##_member)) { \ if (pf->pFunc##_member) Py_DECREF(pf->pFunc##_member); \ DEBUG(1, ("vfs_python: %s function not found or not callable\n", _name)); \ errno = E_INTERNAL; \ return -1; \ } #define VFS_PY_OPTIONAL_MODULE_FUNC(_member, _name) \ pf->pFunc##_member = PyObject_GetAttrString(pf->pModule, _name); \ if (!pf->pFunc##_member) { \ pf->pFunc##_member = NULL; \ PyErr_Clear(); \ } \ else if (!PyCallable_Check(pf->pFunc##_member)) { \ Py_DECREF(pf->pFunc##_member); \ pf->pFunc##_member = NULL; \ } pf->pErrno = PyObject_GetAttrString(pf->pModule, "vfs_errno"); if (pf->pErrno && !PyInt_Check(pf->pErrno)) { Py_DECREF(pf->pErrno); DEBUG(1, ("vfs_python: vfs_errno global variable not an int\n")); errno = E_INTERNAL; return -1; } VFS_PY_REQUIRED_MODULE_FUNC(Stat, "stat"); VFS_PY_REQUIRED_MODULE_FUNC(GetDir, "getdir"); VFS_PY_REQUIRED_MODULE_FUNC(OpenFile, "open"); VFS_PY_REQUIRED_MODULE_FUNC(Close, "close"); VFS_PY_REQUIRED_MODULE_FUNC(Read, "read"); VFS_PY_REQUIRED_MODULE_FUNC(LSeek, "lseek"); VFS_PY_OPTIONAL_MODULE_FUNC(Unlink, "unlink"); VFS_PY_OPTIONAL_MODULE_FUNC(Write, "write"); VFS_PY_OPTIONAL_MODULE_FUNC(MkDir, "mkdir"); VFS_PY_OPTIONAL_MODULE_FUNC(Unlink, "unlink"); VFS_PY_OPTIONAL_MODULE_FUNC(Rename, "rename"); VFS_PY_OPTIONAL_MODULE_FUNC(FStat, "fstat"); VFS_PY_OPTIONAL_MODULE_FUNC(DiskFree, "diskfree"); VFS_PY_OPTIONAL_MODULE_FUNC(Connect, "connect"); VFS_PY_OPTIONAL_MODULE_FUNC(Disconnect, "disconnect"); VFS_PY_OPTIONAL_MODULE_FUNC(PRead, "pread"); VFS_PY_OPTIONAL_MODULE_FUNC(PWrite, "pwrite"); VFS_PY_OPTIONAL_MODULE_FUNC(Chmod, "chmod"); VFS_PY_OPTIONAL_MODULE_FUNC(FChmod, "fchmod"); VFS_PY_OPTIONAL_MODULE_FUNC(Chown, "chown"); VFS_PY_OPTIONAL_MODULE_FUNC(FChown, "fchown"); VFS_PY_OPTIONAL_MODULE_FUNC(FTruncate, "ftruncate"); VFS_PY_OPTIONAL_MODULE_FUNC(FAllocate, "fallocate"); VFS_PY_OPTIONAL_MODULE_FUNC(Symlink, "symlink"); VFS_PY_OPTIONAL_MODULE_FUNC(Link, "link"); VFS_PY_OPTIONAL_MODULE_FUNC(ReadLink, "readlink"); VFS_PY_OPTIONAL_MODULE_FUNC(IsOffline, "isoffline"); VFS_PY_OPTIONAL_MODULE_FUNC(GetPath, "getpath"); // Init done, do connect if (pf->pFuncConnect) { PY_TUPLE_NEW(3); PY_ADD_TO_TUPLE(service, PyString_FromString, 0); PY_ADD_TO_TUPLE(user, PyString_FromString, 1); pyarg = lp_parm_const_string(SNUM(handle->conn), "vfs_python", "connect_arg", NULL); if (pyarg) { PY_ADD_TO_TUPLE(pyarg, PyString_FromString, 2); } else { PyTuple_SetItem(pArgs, 2, Py_None); } PY_CALL_WITH_ARGS(Connect); i = PyInt_AS_LONG(pRet); Py_DECREF(pRet); return i; } return 0; }
/* convert a filename from a share relative path, to a path in the snapshot directory */ static char *convert_shadow2_name(vfs_handle_struct *handle, const char *fname, const char *gmt_path) { TALLOC_CTX *tmp_ctx = talloc_new(handle->data); const char *snapdir, *relpath, *baseoffset, *basedir; size_t baselen; char *ret, *prefix; struct tm timestamp; time_t timestamp_t; char snapshot[MAXPATHLEN]; const char *fmt; fmt = lp_parm_const_string(SNUM(handle->conn), "shadow", "format", SHADOW_COPY2_DEFAULT_FORMAT); snapdir = shadow_copy2_find_snapdir(tmp_ctx, handle); if (snapdir == NULL) { DEBUG(2,("no snapdir found for share at %s\n", handle->conn->connectpath)); talloc_free(tmp_ctx); return NULL; } basedir = shadow_copy2_find_basedir(tmp_ctx, handle); if (basedir == NULL) { DEBUG(2,("no basedir found for share at %s\n", handle->conn->connectpath)); talloc_free(tmp_ctx); return NULL; } prefix = talloc_asprintf(tmp_ctx, "%s/@GMT-", snapdir); if (strncmp(fname, prefix, (talloc_get_size(prefix)-1)) == 0) { /* this looks like as we have already normalized it, leave it untouched*/ talloc_free(tmp_ctx); return talloc_strdup(handle->data, fname); } if (strncmp(fname, "@GMT-", 5) != 0) { fname = shadow_copy2_normalise_path(tmp_ctx, fname, gmt_path); if (fname == NULL) { talloc_free(tmp_ctx); return NULL; } } ZERO_STRUCT(timestamp); relpath = strptime(fname, SHADOW_COPY2_GMT_FORMAT, ×tamp); if (relpath == NULL) { talloc_free(tmp_ctx); return NULL; } /* relpath is the remaining portion of the path after the @GMT-xxx */ if (lp_parm_bool(SNUM(handle->conn), "shadow", "localtime", SHADOW_COPY2_DEFAULT_LOCALTIME)) { timestamp_t = timegm(×tamp); localtime_r(×tamp_t, ×tamp); } strftime(snapshot, MAXPATHLEN, fmt, ×tamp); baselen = strlen(basedir); baseoffset = handle->conn->connectpath + baselen; /* some sanity checks */ if (strncmp(basedir, handle->conn->connectpath, baselen) != 0 || (handle->conn->connectpath[baselen] != 0 && handle->conn->connectpath[baselen] != '/')) { DEBUG(0,("convert_shadow2_name: basedir %s is not a parent of %s\n", basedir, handle->conn->connectpath)); talloc_free(tmp_ctx); return NULL; } if (*relpath == '/') relpath++; if (*baseoffset == '/') baseoffset++; ret = talloc_asprintf(handle->data, "%s/%s/%s/%s", snapdir, snapshot, baseoffset, relpath); DEBUG(6,("convert_shadow2_name: '%s' -> '%s'\n", fname, ret)); talloc_free(tmp_ctx); return ret; }
static NTSTATUS script_check_user_credentials(const struct auth_context *auth_context, void *my_private_data, TALLOC_CTX *mem_ctx, const auth_usersupplied_info *user_info, auth_serversupplied_info **server_info) { const char *script = lp_parm_const_string( GLOBAL_SECTION_SNUM, "auth_script", "script", NULL); char *secret_str; size_t secret_str_len; char hex_str[49]; int ret, i; if (!script) { return NT_STATUS_INVALID_PARAMETER; } if (!user_info) { return NT_STATUS_INVALID_PARAMETER; } if (!auth_context) { DEBUG(3,("script_check_user_credentials: no auth_info !\n")); return NT_STATUS_INVALID_PARAMETER; } secret_str_len = strlen(user_info->domain) + 1 + strlen(user_info->smb_name) + 1 + 16 + 1 + /* 8 bytes of challenge going to 16 */ 48 + 1 + /* 24 bytes of challenge going to 48 */ 48 + 1; secret_str = (char *)malloc(secret_str_len); if (!secret_str) { return NT_STATUS_NO_MEMORY; } safe_strcpy( secret_str, user_info->domain, secret_str_len - 1); safe_strcat( secret_str, "\n", secret_str_len - 1); safe_strcat( secret_str, user_info->smb_name, secret_str_len - 1); safe_strcat( secret_str, "\n", secret_str_len - 1); for (i = 0; i < 8; i++) { slprintf(&hex_str[i*2], 3, "%02X", auth_context->challenge.data[i]); } safe_strcat( secret_str, hex_str, secret_str_len - 1); safe_strcat( secret_str, "\n", secret_str_len - 1); if (user_info->lm_resp.data) { for (i = 0; i < 24; i++) { slprintf(&hex_str[i*2], 3, "%02X", user_info->lm_resp.data[i]); } safe_strcat( secret_str, hex_str, secret_str_len - 1); } safe_strcat( secret_str, "\n", secret_str_len - 1); if (user_info->nt_resp.data) { for (i = 0; i < 24; i++) { slprintf(&hex_str[i*2], 3, "%02X", user_info->nt_resp.data[i]); } safe_strcat( secret_str, hex_str, secret_str_len - 1); } safe_strcat( secret_str, "\n", secret_str_len - 1); DEBUG(10,("script_check_user_credentials: running %s with parameters:\n%s\n", script, secret_str )); ret = smbrunsecret( script, secret_str); SAFE_FREE(secret_str); if (ret) { DEBUG(1,("script_check_user_credentials: failed to authenticate %s\\%s\n", user_info->domain, user_info->smb_name )); /* auth failed. */ return NT_STATUS_NO_SUCH_USER; } /* Cause the auth system to keep going.... */ return NT_STATUS_NOT_IMPLEMENTED; }
static NTSTATUS shell_snap_create(struct vfs_handle_struct *handle, TALLOC_CTX *mem_ctx, const char *base_volume, time_t *tstamp, bool rw, char **base_path, char **snap_path) { const char *cmd; char *cmd_run; char **qlines; int numlines, ret; int fd = -1; TALLOC_CTX *tmp_ctx; NTSTATUS status; cmd = lp_parm_const_string(handle->conn->params->service, "shell_snap", "create command", ""); if ((cmd == NULL) || (strlen(cmd) == 0)) { DEBUG(1, ("\"shell_snap:create command\" not configured\n")); status = NT_STATUS_NOT_SUPPORTED; goto err_out; } tmp_ctx = talloc_new(mem_ctx); if (tmp_ctx == NULL) { status = NT_STATUS_NO_MEMORY; goto err_out; } /* add base vol argument */ cmd_run = talloc_asprintf(tmp_ctx, "%s %s", cmd, base_volume); if (cmd_run == NULL) { status = NT_STATUS_NO_MEMORY; goto err_tmp_free; } ret = smbrun(cmd_run, &fd); talloc_free(cmd_run); if (ret != 0) { if (fd != -1) { close(fd); } status = NT_STATUS_UNSUCCESSFUL; goto err_tmp_free; } numlines = 0; qlines = fd_lines_load(fd, &numlines, PATH_MAX + 1, tmp_ctx); close(fd); /* script must return the snapshot path as a single line */ if ((numlines == 0) || (qlines == NULL) || (qlines[0] == NULL)) { status = NT_STATUS_UNSUCCESSFUL; goto err_tmp_free; } *base_path = talloc_strdup(mem_ctx, base_volume); if (*base_path == NULL) { status = NT_STATUS_NO_MEMORY; goto err_tmp_free; } *snap_path = talloc_strdup(mem_ctx, qlines[0]); if (*snap_path == NULL) { status = NT_STATUS_NO_MEMORY; talloc_free(*base_path); goto err_tmp_free; } status = NT_STATUS_OK; err_tmp_free: talloc_free(tmp_ctx); err_out: return status; }
static const char *nmbd_socket_dir(void) { return lp_parm_const_string(-1, "nmbd", "socket dir", get_dyn_NMBDSOCKETDIR()); }
/* called when a client connects to a share */ static int tsmsm_connect(struct vfs_handle_struct *handle, const char *service, const char *user) { struct tsmsm_struct *tsmd; const char *fres; const char *tsmname; int ret = SMB_VFS_NEXT_CONNECT(handle, service, user); if (ret < 0) { return ret; } tsmd = talloc_zero(handle, struct tsmsm_struct); if (!tsmd) { SMB_VFS_NEXT_DISCONNECT(handle); DEBUG(0,("tsmsm_connect: out of memory!\n")); return -1; } if (!dmapi_have_session()) { SMB_VFS_NEXT_DISCONNECT(handle); DEBUG(0,("tsmsm_connect: no DMAPI session for Samba is available!\n")); TALLOC_FREE(tsmd); return -1; } tsmname = (handle->param ? handle->param : "tsmsm"); /* Get 'hsm script' and 'dmapi attribute' parameters to tsmd context */ tsmd->hsmscript = lp_parm_talloc_string( tsmd, SNUM(handle->conn), tsmname, "hsm script", NULL); talloc_steal(tsmd, tsmd->hsmscript); tsmd->attrib_name = lp_parm_talloc_string( tsmd, SNUM(handle->conn), tsmname, "dmapi attribute", DM_ATTRIB_OBJECT); talloc_steal(tsmd, tsmd->attrib_name); tsmd->attrib_value = lp_parm_talloc_string( tsmd, SNUM(handle->conn), tsmname, "dmapi value", NULL); talloc_steal(tsmd, tsmd->attrib_value); /* retrieve 'online ratio'. In case of error default to FILE_IS_ONLINE_RATIO */ fres = lp_parm_const_string(SNUM(handle->conn), tsmname, "online ratio", NULL); if (fres == NULL) { tsmd->online_ratio = FILE_IS_ONLINE_RATIO; } else { tsmd->online_ratio = strtof(fres, NULL); if (tsmd->online_ratio > 1.0 || tsmd->online_ratio <= 0.0) { DEBUG(1, ("tsmsm_connect: invalid online ration %f - using %f.\n", tsmd->online_ratio, (float)FILE_IS_ONLINE_RATIO)); } } /* Store the private data. */ SMB_VFS_HANDLE_SET_DATA(handle, tsmd, tsmsm_free_data, struct tsmsm_struct, return -1); return 0; }
static NTSTATUS idmap_ldap_alloc_init(const char *params) { NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; const char *range; const char *tmp; uid_t low_uid = 0; uid_t high_uid = 0; gid_t low_gid = 0; gid_t high_gid = 0; /* Only do init if we are online */ if (idmap_is_offline()) { return NT_STATUS_FILE_IS_OFFLINE; } idmap_alloc_ldap = TALLOC_ZERO_P(NULL, struct idmap_ldap_alloc_context); CHECK_ALLOC_DONE( idmap_alloc_ldap ); /* load ranges */ idmap_alloc_ldap->low_uid = 0; idmap_alloc_ldap->high_uid = 0; idmap_alloc_ldap->low_gid = 0; idmap_alloc_ldap->high_gid = 0; range = lp_parm_const_string(-1, "idmap alloc config", "range", NULL); if (range && range[0]) { unsigned low_id, high_id; if (sscanf(range, "%u - %u", &low_id, &high_id) == 2) { if (low_id < high_id) { idmap_alloc_ldap->low_gid = low_id; idmap_alloc_ldap->low_uid = low_id; idmap_alloc_ldap->high_gid = high_id; idmap_alloc_ldap->high_uid = high_id; } else { DEBUG(1, ("ERROR: invalid idmap alloc range " "[%s]", range)); } } else { DEBUG(1, ("ERROR: invalid syntax for idmap alloc " "config:range [%s]", range)); } } if (lp_idmap_uid(&low_uid, &high_uid)) { idmap_alloc_ldap->low_uid = low_uid; idmap_alloc_ldap->high_uid = high_uid; } if (lp_idmap_gid(&low_gid, &high_gid)) { idmap_alloc_ldap->low_gid = low_gid; idmap_alloc_ldap->high_gid= high_gid; } if (idmap_alloc_ldap->high_uid <= idmap_alloc_ldap->low_uid) { DEBUG(1, ("idmap uid range missing or invalid\n")); DEBUGADD(1, ("idmap will be unable to map foreign SIDs\n")); ret = NT_STATUS_UNSUCCESSFUL; goto done; } if (idmap_alloc_ldap->high_gid <= idmap_alloc_ldap->low_gid) { DEBUG(1, ("idmap gid range missing or invalid\n")); DEBUGADD(1, ("idmap will be unable to map foreign SIDs\n")); ret = NT_STATUS_UNSUCCESSFUL; goto done; } if (params && *params) { /* assume location is the only parameter */ idmap_alloc_ldap->url = talloc_strdup(idmap_alloc_ldap, params); } else { tmp = lp_parm_const_string(-1, "idmap alloc config", "ldap_url", NULL); if ( ! tmp) { DEBUG(1, ("ERROR: missing idmap ldap url\n")); ret = NT_STATUS_UNSUCCESSFUL; goto done; } idmap_alloc_ldap->url = talloc_strdup(idmap_alloc_ldap, tmp); } CHECK_ALLOC_DONE( idmap_alloc_ldap->url ); tmp = lp_parm_const_string(-1, "idmap alloc config", "ldap_base_dn", NULL); if ( ! tmp || ! *tmp) { tmp = lp_ldap_idmap_suffix(); if ( ! tmp) { DEBUG(1, ("ERROR: missing idmap ldap suffix\n")); ret = NT_STATUS_UNSUCCESSFUL; goto done; } } idmap_alloc_ldap->suffix = talloc_strdup(idmap_alloc_ldap, tmp); CHECK_ALLOC_DONE( idmap_alloc_ldap->suffix ); ret = smbldap_init(idmap_alloc_ldap, winbind_event_context(), idmap_alloc_ldap->url, &idmap_alloc_ldap->smbldap_state); if (!NT_STATUS_IS_OK(ret)) { DEBUG(1, ("ERROR: smbldap_init (%s) failed!\n", idmap_alloc_ldap->url)); goto done; } ret = get_credentials( idmap_alloc_ldap, idmap_alloc_ldap->smbldap_state, "idmap alloc config", NULL, &idmap_alloc_ldap->user_dn ); if ( !NT_STATUS_IS_OK(ret) ) { DEBUG(1,("idmap_ldap_alloc_init: Failed to get connection " "credentials (%s)\n", nt_errstr(ret))); goto done; } /* see if the idmap suffix and sub entries exists */ ret = verify_idpool(); done: if ( !NT_STATUS_IS_OK( ret ) ) TALLOC_FREE( idmap_alloc_ldap ); return ret; }
static NTSTATUS idmap_ldap_db_init(struct idmap_domain *dom) { NTSTATUS ret; struct idmap_ldap_context *ctx = NULL; char *config_option = NULL; const char *range = NULL; const char *tmp = NULL; /* Only do init if we are online */ if (idmap_is_offline()) { return NT_STATUS_FILE_IS_OFFLINE; } ctx = TALLOC_ZERO_P(dom, struct idmap_ldap_context); if ( ! ctx) { DEBUG(0, ("Out of memory!\n")); return NT_STATUS_NO_MEMORY; } config_option = talloc_asprintf(ctx, "idmap config %s", dom->name); if ( ! config_option) { DEBUG(0, ("Out of memory!\n")); ret = NT_STATUS_NO_MEMORY; goto done; } /* load ranges */ range = lp_parm_const_string(-1, config_option, "range", NULL); if (range && range[0]) { if ((sscanf(range, "%u - %u", &ctx->filter_low_id, &ctx->filter_high_id) != 2) || (ctx->filter_low_id > ctx->filter_high_id)) { DEBUG(1, ("ERROR: invalid filter range [%s]", range)); ctx->filter_low_id = 0; ctx->filter_high_id = 0; } } if (dom->params && *(dom->params)) { /* assume location is the only parameter */ ctx->url = talloc_strdup(ctx, dom->params); } else { tmp = lp_parm_const_string(-1, config_option, "ldap_url", NULL); if ( ! tmp) { DEBUG(1, ("ERROR: missing idmap ldap url\n")); ret = NT_STATUS_UNSUCCESSFUL; goto done; } ctx->url = talloc_strdup(ctx, tmp); } CHECK_ALLOC_DONE(ctx->url); tmp = lp_parm_const_string(-1, config_option, "ldap_base_dn", NULL); if ( ! tmp || ! *tmp) { tmp = lp_ldap_idmap_suffix(); if ( ! tmp) { DEBUG(1, ("ERROR: missing idmap ldap suffix\n")); ret = NT_STATUS_UNSUCCESSFUL; goto done; } } ctx->suffix = talloc_strdup(ctx, tmp); CHECK_ALLOC_DONE(ctx->suffix); ret = smbldap_init(ctx, winbind_event_context(), ctx->url, &ctx->smbldap_state); if (!NT_STATUS_IS_OK(ret)) { DEBUG(1, ("ERROR: smbldap_init (%s) failed!\n", ctx->url)); goto done; } ret = get_credentials( ctx, ctx->smbldap_state, config_option, dom, &ctx->user_dn ); if ( !NT_STATUS_IS_OK(ret) ) { DEBUG(1,("idmap_ldap_db_init: Failed to get connection " "credentials (%s)\n", nt_errstr(ret))); goto done; } /* set the destructor on the context, so that resource are properly freed if the contexts is released */ talloc_set_destructor(ctx, idmap_ldap_close_destructor); dom->private_data = ctx; dom->initialized = True; talloc_free(config_option); return NT_STATUS_OK; /*failed */ done: talloc_free(ctx); return ret; }
static int net_idmap_secret(struct net_context *c, int argc, const char **argv) { TALLOC_CTX *ctx; const char *secret; const char *dn; char *domain; char *backend; char *opt = NULL; bool ret; if (argc != 2 || c->display_usage) { d_printf(_("Usage:\n" "net idmap secret {<DOMAIN>|alloc} <secret>\n" " Set the secret for the specified domain " "(or alloc module)\n" " DOMAIN\tDomain to set secret for.\n" " alloc\tSet secret for the alloc module\n" " secret\tNew secret to set.\n")); return c->display_usage?0:-1; } secret = argv[1]; ctx = talloc_new(NULL); ALLOC_CHECK(ctx); if (strcmp(argv[0], "alloc") == 0) { domain = NULL; backend = lp_idmap_alloc_backend(); } else { domain = talloc_strdup(ctx, argv[0]); ALLOC_CHECK(domain); opt = talloc_asprintf(ctx, "idmap config %s", domain); ALLOC_CHECK(opt); backend = talloc_strdup(ctx, lp_parm_const_string(-1, opt, "backend", "tdb")); ALLOC_CHECK(backend); } if ( ( ! backend) || ( ! strequal(backend, "ldap"))) { d_fprintf(stderr, _("The only currently supported backend is LDAP\n")); talloc_free(ctx); return -1; } if (domain) { dn = lp_parm_const_string(-1, opt, "ldap_user_dn", NULL); if ( ! dn) { d_fprintf(stderr, _("Missing ldap_user_dn option for domain " "%s\n"), domain); talloc_free(ctx); return -1; } ret = idmap_store_secret("ldap", false, domain, dn, secret); } else { dn = lp_parm_const_string(-1, "idmap alloc config", "ldap_user_dn", NULL); if ( ! dn) { d_fprintf(stderr, _("Missing ldap_user_dn option for alloc " "backend\n")); talloc_free(ctx); return -1; } ret = idmap_store_secret("ldap", true, NULL, dn, secret); } if ( ! ret) { d_fprintf(stderr, _("Failed to store secret\n")); talloc_free(ctx); return -1; } d_printf(_("Secret stored\n")); return 0; }
static NTSTATUS check_netlogond_security(const struct auth_context *auth_context, void *my_private_data, TALLOC_CTX *mem_ctx, const struct auth_usersupplied_info *user_info, struct auth_serversupplied_info **server_info) { TALLOC_CTX *frame = talloc_stackframe(); struct netr_SamInfo3 *info3 = NULL; struct rpc_pipe_client *p = NULL; struct pipe_auth_data *auth = NULL; uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS; uint8_t machine_password[16]; struct netlogon_creds_CredentialState *creds; NTSTATUS schannel_bind_result, status; struct named_mutex *mutex = NULL; const char *ncalrpcsock; DEBUG(10, ("Check auth for: [%s]\n", user_info->mapped.account_name)); ncalrpcsock = lp_parm_const_string( GLOBAL_SECTION_SNUM, "auth_netlogond", "socket", NULL); if (ncalrpcsock == NULL) { ncalrpcsock = talloc_asprintf(talloc_tos(), "%s/%s", get_dyn_NCALRPCDIR(), "DEFAULT"); } if (ncalrpcsock == NULL) { status = NT_STATUS_NO_MEMORY; goto done; } creds = secrets_fetch_local_schannel_creds(talloc_tos()); if (creds == NULL) { goto new_key; } status = netlogond_validate(talloc_tos(), auth_context, ncalrpcsock, creds, user_info, &info3, &schannel_bind_result); DEBUG(10, ("netlogond_validate returned %s\n", nt_errstr(status))); if (NT_STATUS_IS_OK(status)) { goto okay; } if (NT_STATUS_IS_OK(schannel_bind_result)) { /* * This is a real failure from the DC */ goto done; } new_key: mutex = grab_named_mutex(talloc_tos(), "LOCAL_SCHANNEL_KEY", 60); if (mutex == NULL) { DEBUG(10, ("Could not get mutex LOCAL_SCHANNEL_KEY\n")); status = NT_STATUS_ACCESS_DENIED; goto done; } DEBUG(10, ("schannel bind failed, setting up new key\n")); status = rpc_pipe_open_ncalrpc(talloc_tos(), ncalrpcsock, &ndr_table_netlogon.syntax_id, &p); if (!NT_STATUS_IS_OK(status)) { DEBUG(10, ("rpc_pipe_open_ncalrpc failed: %s\n", nt_errstr(status))); goto done; } status = rpccli_anon_bind_data(p, &auth); if (!NT_STATUS_IS_OK(status)) { DEBUG(10, ("rpccli_anon_bind_data failed: %s\n", nt_errstr(status))); goto done; } status = rpc_pipe_bind(p, auth); if (!NT_STATUS_IS_OK(status)) { DEBUG(10, ("rpc_pipe_bind failed: %s\n", nt_errstr(status))); goto done; } status = mymachinepw(machine_password); if (!NT_STATUS_IS_OK(status)) { DEBUG(10, ("mymachinepw failed: %s\n", nt_errstr(status))); goto done; } DEBUG(10, ("machinepw ")); dump_data(10, machine_password, 16); status = rpccli_netlogon_setup_creds( p, lp_netbios_name(), lp_workgroup(), lp_netbios_name(), lp_netbios_name(), machine_password, SEC_CHAN_BDC, &neg_flags); if (!NT_STATUS_IS_OK(status)) { DEBUG(10, ("rpccli_netlogon_setup_creds failed: %s\n", nt_errstr(status))); goto done; } secrets_store_local_schannel_creds(p->dc); /* * Retry the authentication with the mutex held. This way nobody else * can step on our toes. */ status = netlogond_validate(talloc_tos(), auth_context, ncalrpcsock, p->dc, user_info, &info3, &schannel_bind_result); TALLOC_FREE(p); DEBUG(10, ("netlogond_validate returned %s\n", nt_errstr(status))); if (!NT_STATUS_IS_OK(status)) { goto done; } okay: status = make_server_info_info3(mem_ctx, user_info->client.account_name, user_info->mapped.domain_name, server_info, info3); if (!NT_STATUS_IS_OK(status)) { DEBUG(10, ("make_server_info_info3 failed: %s\n", nt_errstr(status))); TALLOC_FREE(frame); return status; } status = NT_STATUS_OK; done: TALLOC_FREE(frame); return status; }
static int net_idmap_secret(int argc, const char **argv) { TALLOC_CTX *ctx; const char *secret; const char *dn; char *domain; char *backend; char *opt = NULL; bool ret; if (argc != 2) { return net_help_idmap(argc, argv); } secret = argv[1]; ctx = talloc_new(NULL); ALLOC_CHECK(ctx); if (strcmp(argv[0], "alloc") == 0) { domain = NULL; backend = lp_idmap_alloc_backend(); } else { domain = talloc_strdup(ctx, argv[0]); ALLOC_CHECK(domain); opt = talloc_asprintf(ctx, "idmap config %s", domain); ALLOC_CHECK(opt); backend = talloc_strdup(ctx, lp_parm_const_string(-1, opt, "backend", "tdb")); ALLOC_CHECK(backend); } if ( ( ! backend) || ( ! strequal(backend, "ldap"))) { d_fprintf(stderr, "The only currently supported backend is LDAP\n"); talloc_free(ctx); return -1; } if (domain) { dn = lp_parm_const_string(-1, opt, "ldap_user_dn", NULL); if ( ! dn) { d_fprintf(stderr, "Missing ldap_user_dn option for domain %s\n", domain); talloc_free(ctx); return -1; } ret = idmap_store_secret("ldap", false, domain, dn, secret); } else { dn = lp_parm_const_string(-1, "idmap alloc config", "ldap_user_dn", NULL); if ( ! dn) { d_fprintf(stderr, "Missing ldap_user_dn option for alloc backend\n"); talloc_free(ctx); return -1; } ret = idmap_store_secret("ldap", true, NULL, dn, secret); } if ( ! ret) { d_fprintf(stderr, "Failed to store secret\n"); talloc_free(ctx); return -1; } d_printf("Secret stored\n"); return 0; }
static BOOL afs_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp, uint32 security_info_sent, struct security_descriptor *psd) { struct afs_acl old_afs_acl, new_afs_acl; struct afs_acl dir_acl, file_acl; char acl_string[2049]; struct afs_iob iob; int ret = -1; pstring name; const char *fileacls; fileacls = lp_parm_const_string(SNUM(handle->conn), "afsacl", "fileacls", "yes"); sidpts = lp_parm_bool(SNUM(handle->conn), "afsacl", "sidpts", False); ZERO_STRUCT(old_afs_acl); ZERO_STRUCT(new_afs_acl); ZERO_STRUCT(dir_acl); ZERO_STRUCT(file_acl); pstrcpy(name, fsp->fsp_name); if (!fsp->is_directory) { /* We need to get the name of the directory containing the * file, this is where the AFS acls live */ char *p = strrchr(name, '/'); if (p != NULL) { *p = '\0'; } else { pstrcpy(name, "."); } } if (!afs_get_afs_acl(name, &old_afs_acl)) { DEBUG(3, ("Could not get old ACL of %s\n", fsp->fsp_name)); goto done; } split_afs_acl(&old_afs_acl, &dir_acl, &file_acl); if (fsp->is_directory) { if (!strequal(fileacls, "yes")) { /* Throw away file acls, we depend on the * inheritance ACEs that also give us file * permissions */ free_afs_acl(&file_acl); } free_afs_acl(&dir_acl); if (!nt_to_afs_acl(fsp->fsp_name, security_info_sent, psd, nt_to_afs_dir_rights, &dir_acl)) goto done; } else { if (strequal(fileacls, "no")) { ret = -1; goto done; } if (strequal(fileacls, "ignore")) { ret = 0; goto done; } free_afs_acl(&file_acl); if (!nt_to_afs_acl(fsp->fsp_name, security_info_sent, psd, nt_to_afs_file_rights, &file_acl)) goto done; } merge_afs_acls(&dir_acl, &file_acl, &new_afs_acl); merge_unknown_aces(&old_afs_acl, &new_afs_acl); unparse_afs_acl(&new_afs_acl, acl_string); iob.in = acl_string; iob.in_size = 1+strlen(iob.in); iob.out = NULL; iob.out_size = 0; DEBUG(10, ("trying to set acl '%s' on file %s\n", iob.in, name)); ret = afs_syscall(AFSCALL_PIOCTL, name, VIOCSETAL, (char *)&iob, 0); if (ret != 0) { DEBUG(10, ("VIOCSETAL returned %d\n", ret)); } done: free_afs_acl(&dir_acl); free_afs_acl(&file_acl); free_afs_acl(&old_afs_acl); free_afs_acl(&new_afs_acl); return (ret == 0); }
static NTSTATUS discover_dc_dns(TALLOC_CTX *mem_ctx, const char *domain_name, const struct GUID *domain_guid, uint32_t flags, const char *site_name, struct ip_service_name **returned_dclist, int *return_count) { int i, j; NTSTATUS status; struct dns_rr_srv *dcs = NULL; int numdcs = 0; int numaddrs = 0; struct ip_service_name *dclist = NULL; int count = 0; const char *dns_hosts_file; char *guid_string; dns_hosts_file = lp_parm_const_string(-1, "resolv", "host file", NULL); if (flags & DS_PDC_REQUIRED) { status = ads_dns_query_pdc(mem_ctx, dns_hosts_file, domain_name, &dcs, &numdcs); } else if (flags & DS_GC_SERVER_REQUIRED) { status = ads_dns_query_gcs(mem_ctx, dns_hosts_file, domain_name, site_name, &dcs, &numdcs); } else if (flags & DS_KDC_REQUIRED) { status = ads_dns_query_kdcs(mem_ctx, dns_hosts_file, domain_name, site_name, &dcs, &numdcs); } else if (flags & DS_DIRECTORY_SERVICE_REQUIRED) { status = ads_dns_query_dcs(mem_ctx, dns_hosts_file, domain_name, site_name, &dcs, &numdcs); } else if (domain_guid) { guid_string = GUID_string(mem_ctx, domain_guid); if (!guid_string) { return NT_STATUS_NO_MEMORY; } status = ads_dns_query_dcs_guid(mem_ctx, dns_hosts_file, domain_name, guid_string, &dcs, &numdcs); TALLOC_FREE(guid_string); } else { status = ads_dns_query_dcs(mem_ctx, dns_hosts_file, domain_name, site_name, &dcs, &numdcs); } if (!NT_STATUS_IS_OK(status)) { return status; } if (numdcs == 0) { return NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND; } for (i=0;i<numdcs;i++) { numaddrs += MAX(dcs[i].num_ips,1); } dclist = talloc_zero_array(mem_ctx, struct ip_service_name, numaddrs); if (!dclist) { return NT_STATUS_NO_MEMORY; } /* now unroll the list of IP addresses */ *return_count = 0; i = 0; j = 0; while ((i < numdcs) && (count < numaddrs)) { struct ip_service_name *r = &dclist[count]; r->hostname = dcs[i].hostname; /* If we don't have an IP list for a name, lookup it up */ if (!dcs[i].ss_s) { interpret_string_addr_prefer_ipv4(&r->ss, dcs[i].hostname, 0); i++; j = 0; } else { /* use the IP addresses from the SRV response */ if (j >= dcs[i].num_ips) { i++; j = 0; continue; } r->ss = dcs[i].ss_s[j]; j++; } /* make sure it is a valid IP. I considered checking the * negative connection cache, but this is the wrong place for * it. Maybe only as a hack. After think about it, if all of * the IP addresses returned from DNS are dead, what hope does a * netbios name lookup have? The standard reason for falling * back to netbios lookups is that our DNS server doesn't know * anything about the DC's -- jerry */ if (!is_zero_addr(&r->ss)) { count++; continue; } } *returned_dclist = dclist; *return_count = count; if (count > 0) { return NT_STATUS_OK; } return NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND; }
/* load the idmap allocation ranges and high/low water marks */ static NTSTATUS idmap_tdb2_alloc_load(void) { uid_t low_uid = 0; uid_t high_uid = 0; gid_t low_gid = 0; gid_t high_gid = 0; uint32 low_id; /* see if a idmap script is configured */ idmap_tdb2_state.idmap_script = lp_parm_const_string(-1, "idmap", "script", NULL); if (idmap_tdb2_state.idmap_script) { DEBUG(1, ("using idmap script '%s'\n", idmap_tdb2_state.idmap_script)); } /* load ranges */ /* Create high water marks for group and user id */ if (!lp_idmap_uid(&low_uid, &high_uid) || !lp_idmap_gid(&low_gid, &high_gid)) { DEBUG(1, ("idmap uid or idmap gid missing\n")); return NT_STATUS_UNSUCCESSFUL; } idmap_tdb2_state.low_uid = low_uid; idmap_tdb2_state.high_uid = high_uid; idmap_tdb2_state.low_gid = low_gid; idmap_tdb2_state.high_gid = high_gid; if (idmap_tdb2_state.high_uid <= idmap_tdb2_state.low_uid) { DEBUG(1, ("idmap uid range missing or invalid\n")); DEBUGADD(1, ("idmap will be unable to map foreign SIDs\n")); return NT_STATUS_UNSUCCESSFUL; } if (((low_id = dbwrap_fetch_int32(idmap_tdb2, HWM_USER)) == -1) || (low_id < idmap_tdb2_state.low_uid)) { if (!NT_STATUS_IS_OK(dbwrap_trans_store_int32( idmap_tdb2, HWM_USER, idmap_tdb2_state.low_uid))) { DEBUG(0, ("Unable to initialise user hwm in idmap " "database\n")); return NT_STATUS_INTERNAL_DB_ERROR; } } if (idmap_tdb2_state.high_gid <= idmap_tdb2_state.low_gid) { DEBUG(1, ("idmap gid range missing or invalid\n")); DEBUGADD(1, ("idmap will be unable to map foreign SIDs\n")); return NT_STATUS_UNSUCCESSFUL; } if (((low_id = dbwrap_fetch_int32(idmap_tdb2, HWM_GROUP)) == -1) || (low_id < idmap_tdb2_state.low_gid)) { if (!NT_STATUS_IS_OK(dbwrap_trans_store_int32( idmap_tdb2, HWM_GROUP, idmap_tdb2_state.low_gid))) { DEBUG(0, ("Unable to initialise group hwm in idmap " "database\n")); return NT_STATUS_INTERNAL_DB_ERROR; } } return NT_STATUS_OK; }
static NTSTATUS ep_register(TALLOC_CTX *mem_ctx, const struct ndr_interface_table *iface, const struct dcerpc_binding_vector *bind_vec, const struct GUID *object_guid, const char *annotation, uint32_t replace, uint32_t unregister, struct dcerpc_binding_handle **pbh) { struct rpc_pipe_client *cli = NULL; struct dcerpc_binding_handle *h; struct pipe_auth_data *auth; const char *ncalrpc_sock; const char *rpcsrv_type; struct epm_entry_t *entries; uint32_t num_ents, i; TALLOC_CTX *tmp_ctx; uint32_t result = EPMAPPER_STATUS_OK; NTSTATUS status; if (iface == NULL) { return NT_STATUS_INVALID_PARAMETER; } if (bind_vec == NULL || bind_vec->count == 0) { return NT_STATUS_INVALID_PARAMETER; } tmp_ctx = talloc_stackframe(); if (tmp_ctx == NULL) { return NT_STATUS_NO_MEMORY; } rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM, "rpc_server", "epmapper", "none"); if (StrCaseCmp(rpcsrv_type, "embedded") == 0) { static struct client_address client_id; strlcpy(client_id.addr, "localhost", sizeof(client_id.addr)); client_id.name = "localhost"; status = rpcint_binding_handle(tmp_ctx, &ndr_table_epmapper, &client_id, get_session_info_system(), server_messaging_context(), &h); if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("dcerpc_ep_register: Could not connect to " "epmapper (%s)", nt_errstr(status))); goto done; } } else if (StrCaseCmp(rpcsrv_type, "daemon") == 0) { /* Connect to the endpoint mapper locally */ ncalrpc_sock = talloc_asprintf(tmp_ctx, "%s/%s", lp_ncalrpc_dir(), "EPMAPPER"); if (ncalrpc_sock == NULL) { status = NT_STATUS_NO_MEMORY; goto done; } status = rpc_pipe_open_ncalrpc(tmp_ctx, ncalrpc_sock, &ndr_table_epmapper.syntax_id, &cli); if (!NT_STATUS_IS_OK(status)) { goto done; } status = rpccli_ncalrpc_bind_data(cli, &auth); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("Failed to initialize anonymous bind.\n")); goto done; } status = rpc_pipe_bind(cli, auth); if (!NT_STATUS_IS_OK(status)) { DEBUG(2, ("Failed to bind ncalrpc socket.\n")); goto done; } h = cli->binding_handle; } else { status = NT_STATUS_INVALID_PARAMETER; goto done; } num_ents = bind_vec->count; entries = talloc_array(tmp_ctx, struct epm_entry_t, num_ents); for (i = 0; i < num_ents; i++) { struct dcerpc_binding *map_binding = &bind_vec->bindings[i]; struct epm_twr_t *map_tower; map_tower = talloc_zero(entries, struct epm_twr_t); if (map_tower == NULL) { status = NT_STATUS_NO_MEMORY; goto done; } status = dcerpc_binding_build_tower(entries, map_binding, &map_tower->tower); if (!NT_STATUS_IS_OK(status)) { goto done; } entries[i].tower = map_tower; if (annotation == NULL) { entries[i].annotation = talloc_strdup(entries, ""); } else { entries[i].annotation = talloc_strndup(entries, annotation, EPM_MAX_ANNOTATION_SIZE); } if (entries[i].annotation == NULL) { status = NT_STATUS_NO_MEMORY; goto done; } if (object_guid != NULL) { entries[i].object = *object_guid; } else { entries[i].object = map_binding->object.uuid; } } if (unregister) { status = dcerpc_epm_Delete(h, tmp_ctx, num_ents, entries, &result); } else { status = dcerpc_epm_Insert(h, tmp_ctx, num_ents, entries, replace, &result); } if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("dcerpc_ep_register: Could not insert tower (%s)\n", nt_errstr(status))); goto done; } if (result != EPMAPPER_STATUS_OK) { DEBUG(0, ("dcerpc_ep_register: Could not insert tower (0x%.8x)\n", result)); status = NT_STATUS_UNSUCCESSFUL; goto done; } if (pbh != NULL) { *pbh = talloc_move(mem_ctx, &h); talloc_steal(*pbh, cli); } done: talloc_free(tmp_ctx); return status; }