/* port functions */ static WERROR sptr_EnumPorts(struct ntptr_context *ntptr, TALLOC_CTX *mem_ctx, struct spoolss_EnumPorts *r) { struct ldb_context *sptr_db = talloc_get_type(ntptr->private_data, struct ldb_context); struct ldb_message **msgs; int count; int i; union spoolss_PortInfo *info; count = sptr_db_search(sptr_db, mem_ctx, NULL, &msgs, NULL, "(&(objectclass=port))"); if (count == 0) return WERR_OK; if (count < 0) return WERR_GENERAL_FAILURE; info = talloc_array(mem_ctx, union spoolss_PortInfo, count); W_ERROR_HAVE_NO_MEMORY(info); switch (r->in.level) { case 1: for (i = 0; i < count; i++) { info[i].info1.port_name = samdb_result_string(msgs[i], "port-name", ""); W_ERROR_HAVE_NO_MEMORY(info[i].info1.port_name); } break; case 2: for (i=0; i < count; i++) { info[i].info2.port_name = samdb_result_string(msgs[i], "port-name", ""); W_ERROR_HAVE_NO_MEMORY(info[i].info2.port_name); info[i].info2.monitor_name = samdb_result_string(msgs[i], "monitor-name", ""); W_ERROR_HAVE_NO_MEMORY(info[i].info2.monitor_name); info[i].info2.description = samdb_result_string(msgs[i], "description", ""); W_ERROR_HAVE_NO_MEMORY(info[i].info2.description); info[i].info2.port_type = samdb_result_uint(msgs[i], "port-type", SPOOLSS_PORT_TYPE_WRITE); info[i].info2.reserved = samdb_result_uint(msgs[i], "reserved", 0); } break; default: return WERR_UNKNOWN_LEVEL; } *r->out.info = info; *r->out.count = count; return WERR_OK; }
static NTSTATUS unbecomeDC_ldap_computer_object(struct libnet_UnbecomeDC_state *s) { int ret; struct ldb_result *r; struct ldb_dn *basedn; static const char *attrs[] = { "distinguishedName", "userAccountControl", NULL }; basedn = ldb_dn_new(s, s->ldap.ldb, s->domain.dn_str); NT_STATUS_HAVE_NO_MEMORY(basedn); ret = ldb_search(s->ldap.ldb, s, &r, basedn, LDB_SCOPE_SUBTREE, attrs, "(&(|(objectClass=user)(objectClass=computer))(sAMAccountName=%s$))", s->dest_dsa.netbios_name); talloc_free(basedn); if (ret != LDB_SUCCESS) { return NT_STATUS_LDAP(ret); } else if (r->count != 1) { talloc_free(r); return NT_STATUS_INVALID_NETWORK_RESPONSE; } s->dest_dsa.computer_dn_str = samdb_result_string(r->msgs[0], "distinguishedName", NULL); if (!s->dest_dsa.computer_dn_str) return NT_STATUS_INVALID_NETWORK_RESPONSE; talloc_steal(s, s->dest_dsa.computer_dn_str); s->dest_dsa.user_account_control = samdb_result_uint(r->msgs[0], "userAccountControl", 0); talloc_free(r); return NT_STATUS_OK; }
/* lookup a name for 1 SID */ static NTSTATUS dcesrv_lsa_lookup_sid(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx, struct dom_sid *sid, const char *sid_str, const char **authority_name, const char **name, enum lsa_SidType *rtype) { NTSTATUS status; int ret; uint32_t atype; struct ldb_message **res; struct ldb_dn *domain_dn; const char * const attrs[] = { "sAMAccountName", "sAMAccountType", "cn", NULL}; status = lookup_well_known_sids(mem_ctx, sid_str, authority_name, name, rtype); if (NT_STATUS_IS_OK(status)) { return status; } if (dom_sid_in_domain(state->domain_sid, sid)) { *authority_name = state->domain_name; domain_dn = state->domain_dn; } else if (dom_sid_in_domain(state->builtin_sid, sid)) { *authority_name = NAME_BUILTIN; domain_dn = state->builtin_dn; } else { /* Not well known, our domain or built in */ /* In future, we must look at SID histories, and at trusted domains via winbind */ return NT_STATUS_NOT_FOUND; } ret = gendb_search(state->sam_ldb, mem_ctx, domain_dn, &res, attrs, "objectSid=%s", ldap_encode_ndr_dom_sid(mem_ctx, sid)); if (ret == 1) { *name = ldb_msg_find_attr_as_string(res[0], "sAMAccountName", NULL); if (!*name) { *name = ldb_msg_find_attr_as_string(res[0], "cn", NULL); if (!*name) { *name = talloc_strdup(mem_ctx, sid_str); NT_STATUS_HAVE_NO_MEMORY(*name); } } atype = samdb_result_uint(res[0], "sAMAccountType", 0); *rtype = ds_atype_map(atype); return NT_STATUS_OK; } /* need to re-add a check for an allocated sid */ return NT_STATUS_NOT_FOUND; }
/* Printer Form functions */ static WERROR sptr_GetPrinterForm(struct ntptr_GenericHandle *printer, TALLOC_CTX *mem_ctx, struct spoolss_GetForm *r) { struct ldb_context *sptr_db = talloc_get_type(printer->ntptr->private_data, struct ldb_context); struct ldb_message **msgs; struct ldb_dn *base_dn; int count; union spoolss_FormInfo *info; /* TODO: do checks access here * if (!(printer->access_mask & desired_access)) { * return WERR_FOOBAR; * } */ base_dn = ldb_dn_new_fmt(mem_ctx, sptr_db, "CN=Forms,CN=%s,CN=Printers", printer->object_name); W_ERROR_HAVE_NO_MEMORY(base_dn); count = sptr_db_search(sptr_db, mem_ctx, base_dn, &msgs, NULL, "(&(form-name=%s)(objectClass=form))", r->in.form_name); if (count == 0) return WERR_FOOBAR; if (count > 1) return WERR_FOOBAR; if (count < 0) return WERR_GENERAL_FAILURE; info = talloc(mem_ctx, union spoolss_FormInfo); W_ERROR_HAVE_NO_MEMORY(info); switch (r->in.level) { case 1: info->info1.flags = samdb_result_uint(msgs[0], "flags", SPOOLSS_FORM_BUILTIN); info->info1.form_name = samdb_result_string(msgs[0], "form-name", NULL); W_ERROR_HAVE_NO_MEMORY(info->info1.form_name); info->info1.size.width = samdb_result_uint(msgs[0], "size-width", 0); info->info1.size.height = samdb_result_uint(msgs[0], "size-height", 0); info->info1.area.left = samdb_result_uint(msgs[0], "area-left", 0); info->info1.area.top = samdb_result_uint(msgs[0], "area-top", 0); info->info1.area.right = samdb_result_uint(msgs[0], "area-right", 0); info->info1.area.bottom = samdb_result_uint(msgs[0], "area-bottom", 0); break; default: return WERR_UNKNOWN_LEVEL; } r->out.info = info; return WERR_OK; }
/* PrintServer Form functions */ static WERROR sptr_EnumPrintServerForms(struct ntptr_GenericHandle *server, TALLOC_CTX *mem_ctx, struct spoolss_EnumForms *r) { struct ldb_context *sptr_db = talloc_get_type(server->ntptr->private_data, struct ldb_context); struct ldb_message **msgs; int count; int i; union spoolss_FormInfo *info; count = sptr_db_search(sptr_db, mem_ctx, ldb_dn_new(mem_ctx, sptr_db, "CN=Forms,CN=PrintServer"), &msgs, NULL, "(&(objectClass=form))"); if (count == 0) return WERR_OK; if (count < 0) return WERR_GENERAL_FAILURE; info = talloc_array(mem_ctx, union spoolss_FormInfo, count); W_ERROR_HAVE_NO_MEMORY(info); switch (r->in.level) { case 1: for (i=0; i < count; i++) { info[i].info1.flags = samdb_result_uint(msgs[i], "flags", SPOOLSS_FORM_BUILTIN); info[i].info1.form_name = samdb_result_string(msgs[i], "form-name", NULL); W_ERROR_HAVE_NO_MEMORY(info[i].info1.form_name); info[i].info1.size.width = samdb_result_uint(msgs[i], "size-width", 0); info[i].info1.size.height = samdb_result_uint(msgs[i], "size-height", 0); info[i].info1.area.left = samdb_result_uint(msgs[i], "area-left", 0); info[i].info1.area.top = samdb_result_uint(msgs[i], "area-top", 0); info[i].info1.area.right = samdb_result_uint(msgs[i], "area-right", 0); info[i].info1.area.bottom = samdb_result_uint(msgs[i], "area-bottom", 0); } break; default: return WERR_UNKNOWN_LEVEL; } *r->out.info = info; *r->out.count = count; return WERR_OK; }
static WERROR sptr_DeletePrintServerForm(struct ntptr_GenericHandle *server, TALLOC_CTX *mem_ctx, struct spoolss_DeleteForm *r) { struct ldb_context *sptr_db = talloc_get_type(server->ntptr->private_data, struct ldb_context); struct ldb_message **msgs; const char * const attrs[] = { "flags", NULL}; int count, ret; enum spoolss_FormFlags flags; /* TODO: do checks access here * if (!(server->access_mask & desired_access)) { * return WERR_FOOBAR; * } */ if (!r->in.form_name) { return WERR_FOOBAR; } count = sptr_db_search(sptr_db, mem_ctx, ldb_dn_new(mem_ctx, sptr_db, "CN=Forms,CN=PrintServer"), &msgs, attrs, "(&(form-name=%s)(objectclass=form))", r->in.form_name); if (count == 0) return WERR_FOOBAR; if (count > 1) return WERR_FOOBAR; if (count < 0) return WERR_GENERAL_FAILURE; flags = samdb_result_uint(msgs[0], "flags", SPOOLSS_FORM_BUILTIN); if (flags != SPOOLSS_FORM_USER) { return WERR_FOOBAR; } ret = ldb_delete(sptr_db, msgs[0]->dn); if (ret != 0) { return WERR_FOOBAR; } return WERR_OK; }
/* drsuapi_DsBind */ static WERROR dcesrv_drsuapi_DsBind(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct drsuapi_DsBind *r) { struct drsuapi_bind_state *b_state; struct dcesrv_handle *handle; struct drsuapi_DsBindInfoCtr *bind_info; struct GUID site_guid; struct ldb_result *site_res; struct ldb_dn *server_site_dn; static const char *site_attrs[] = { "objectGUID", NULL }; struct ldb_result *ntds_res; struct ldb_dn *ntds_dn; static const char *ntds_attrs[] = { "ms-DS-ReplicationEpoch", NULL }; uint32_t pid; uint32_t repl_epoch; int ret; struct auth_session_info *auth_info; WERROR werr; r->out.bind_info = NULL; ZERO_STRUCTP(r->out.bind_handle); b_state = talloc_zero(mem_ctx, struct drsuapi_bind_state); W_ERROR_HAVE_NO_MEMORY(b_state); /* if this is a DC connecting, give them system level access */ werr = drs_security_level_check(dce_call, NULL); if (W_ERROR_IS_OK(werr)) { DEBUG(3,(__location__ ": doing DsBind with system_session\n")); auth_info = system_session(dce_call->conn->dce_ctx->lp_ctx); } else { auth_info = dce_call->conn->auth_state.session_info; } /* * connect to the samdb */ b_state->sam_ctx = samdb_connect(b_state, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, auth_info); if (!b_state->sam_ctx) { return WERR_FOOBAR; } /* * find out the guid of our own site */ server_site_dn = samdb_server_site_dn(b_state->sam_ctx, mem_ctx); W_ERROR_HAVE_NO_MEMORY(server_site_dn); ret = ldb_search(b_state->sam_ctx, mem_ctx, &site_res, server_site_dn, LDB_SCOPE_BASE, site_attrs, "(objectClass=*)"); if (ret != LDB_SUCCESS) { return WERR_DS_DRA_INTERNAL_ERROR; } if (site_res->count != 1) { return WERR_DS_DRA_INTERNAL_ERROR; } site_guid = samdb_result_guid(site_res->msgs[0], "objectGUID"); /* * lookup the local servers Replication Epoch */ ntds_dn = samdb_ntds_settings_dn(b_state->sam_ctx); W_ERROR_HAVE_NO_MEMORY(ntds_dn); ret = ldb_search(b_state->sam_ctx, mem_ctx, &ntds_res, ntds_dn, LDB_SCOPE_BASE, ntds_attrs, "(objectClass=*)"); if (ret != LDB_SUCCESS) { return WERR_DS_DRA_INTERNAL_ERROR; } if (ntds_res->count != 1) { return WERR_DS_DRA_INTERNAL_ERROR; } repl_epoch = samdb_result_uint(ntds_res->msgs[0], "ms-DS-ReplicationEpoch", 0); /* * The "process identifier" of the client. * According to the WSPP docs, sectin 5.35, this is * for informational and debugging purposes only. * The assignment is implementation specific. */ pid = 0; /* * store the clients bind_guid */ if (r->in.bind_guid) { b_state->remote_bind_guid = *r->in.bind_guid; } /* * store the clients bind_info */ if (r->in.bind_info) { switch (r->in.bind_info->length) { case 24: { struct drsuapi_DsBindInfo24 *info24; info24 = &r->in.bind_info->info.info24; b_state->remote_info28.supported_extensions = info24->supported_extensions; b_state->remote_info28.site_guid = info24->site_guid; b_state->remote_info28.pid = info24->pid; b_state->remote_info28.repl_epoch = 0; break; } case 28: b_state->remote_info28 = r->in.bind_info->info.info28; break; } } /* * fill in our local bind info 28 */ b_state->local_info28.supported_extensions = 0; b_state->local_info28.supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_BASE; b_state->local_info28.supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_ASYNC_REPLICATION; b_state->local_info28.supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_REMOVEAPI; b_state->local_info28.supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_MOVEREQ_V2; #if 0 /* we don't support MSZIP compression (only decompression) */ b_state->local_info28.supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_GETCHG_COMPRESS; #endif b_state->local_info28.supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_DCINFO_V1; b_state->local_info28.supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_RESTORE_USN_OPTIMIZATION; b_state->local_info28.supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_KCC_EXECUTE; b_state->local_info28.supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_ADDENTRY_V2; b_state->local_info28.supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_LINKED_VALUE_REPLICATION; b_state->local_info28.supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_DCINFO_V2; b_state->local_info28.supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_INSTANCE_TYPE_NOT_REQ_ON_MOD; b_state->local_info28.supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_CRYPTO_BIND; b_state->local_info28.supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_GET_REPL_INFO; b_state->local_info28.supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_STRONG_ENCRYPTION; b_state->local_info28.supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_DCINFO_V01; b_state->local_info28.supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_TRANSITIVE_MEMBERSHIP; b_state->local_info28.supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_ADD_SID_HISTORY; b_state->local_info28.supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_POST_BETA3; b_state->local_info28.supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_00100000; b_state->local_info28.supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_GET_MEMBERSHIPS2; b_state->local_info28.supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_GETCHGREQ_V6; b_state->local_info28.supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_NONDOMAIN_NCS; b_state->local_info28.supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_GETCHGREQ_V8; b_state->local_info28.supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_GETCHGREPLY_V5; b_state->local_info28.supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_GETCHGREPLY_V6; b_state->local_info28.supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_ADDENTRYREPLY_V3; b_state->local_info28.supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_GETCHGREPLY_V7; b_state->local_info28.supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_VERIFY_OBJECT; #if 0 /* we don't support XPRESS compression yet */ b_state->local_info28.supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_XPRESS_COMPRESS; #endif b_state->local_info28.site_guid = site_guid; b_state->local_info28.pid = pid; b_state->local_info28.repl_epoch = repl_epoch; /* * allocate the return bind_info */ bind_info = talloc(mem_ctx, struct drsuapi_DsBindInfoCtr); W_ERROR_HAVE_NO_MEMORY(bind_info); bind_info->length = 28; bind_info->info.info28 = b_state->local_info28; /* * allocate a bind handle */ handle = dcesrv_handle_new(dce_call->context, DRSUAPI_BIND_HANDLE); W_ERROR_HAVE_NO_MEMORY(handle); handle->data = talloc_steal(handle, b_state); /* * prepare reply */ r->out.bind_info = bind_info; *r->out.bind_handle = handle->wire_handle; return WERR_OK; }
/* lookup a SID for 1 name */ static NTSTATUS dcesrv_lsa_lookup_name(struct tevent_context *ev_ctx, struct loadparm_context *lp_ctx, struct lsa_policy_state *state, TALLOC_CTX *mem_ctx, const char *name, const char **authority_name, struct dom_sid **sid, enum lsa_SidType *rtype, uint32_t *rid) { int ret, i; uint32_t atype; struct ldb_message **res; const char * const attrs[] = { "objectSid", "sAMAccountType", NULL}; const char *p; const char *domain; const char *username; struct ldb_dn *domain_dn; struct dom_sid *domain_sid; NTSTATUS status; p = strchr_m(name, '\\'); if (p != NULL) { domain = talloc_strndup(mem_ctx, name, p-name); if (!domain) { return NT_STATUS_NO_MEMORY; } username = p + 1; } else if (strchr_m(name, '@')) { status = crack_name_to_nt4_name(mem_ctx, ev_ctx, lp_ctx, DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL, name, &domain, &username); if (!NT_STATUS_IS_OK(status)) { DEBUG(3, ("Failed to crack name %s into an NT4 name: %s\n", name, nt_errstr(status))); return status; } } else { domain = NULL; username = name; } if (!domain) { /* Look up table of well known names */ status = lookup_well_known_names(mem_ctx, NULL, username, authority_name, sid, rtype); if (NT_STATUS_IS_OK(status)) { dom_sid_split_rid(NULL, *sid, NULL, rid); return NT_STATUS_OK; } if (username == NULL) { *authority_name = NAME_BUILTIN; *sid = dom_sid_parse_talloc(mem_ctx, SID_BUILTIN); *rtype = SID_NAME_DOMAIN; *rid = 0xFFFFFFFF; return NT_STATUS_OK; } if (strcasecmp_m(username, NAME_NT_AUTHORITY) == 0) { *authority_name = NAME_NT_AUTHORITY; *sid = dom_sid_parse_talloc(mem_ctx, SID_NT_AUTHORITY); *rtype = SID_NAME_DOMAIN; dom_sid_split_rid(NULL, *sid, NULL, rid); return NT_STATUS_OK; } if (strcasecmp_m(username, NAME_BUILTIN) == 0) { *authority_name = NAME_BUILTIN; *sid = dom_sid_parse_talloc(mem_ctx, SID_BUILTIN); *rtype = SID_NAME_DOMAIN; *rid = 0xFFFFFFFF; return NT_STATUS_OK; } if (strcasecmp_m(username, state->domain_dns) == 0) { *authority_name = state->domain_name; *sid = state->domain_sid; *rtype = SID_NAME_DOMAIN; *rid = 0xFFFFFFFF; return NT_STATUS_OK; } if (strcasecmp_m(username, state->domain_name) == 0) { *authority_name = state->domain_name; *sid = state->domain_sid; *rtype = SID_NAME_DOMAIN; *rid = 0xFFFFFFFF; return NT_STATUS_OK; } /* Perhaps this is a well known user? */ name = talloc_asprintf(mem_ctx, "%s\\%s", NAME_NT_AUTHORITY, username); if (!name) { return NT_STATUS_NO_MEMORY; } status = dcesrv_lsa_lookup_name(ev_ctx, lp_ctx, state, mem_ctx, name, authority_name, sid, rtype, rid); if (NT_STATUS_IS_OK(status)) { return status; } /* Perhaps this is a BUILTIN user? */ name = talloc_asprintf(mem_ctx, "%s\\%s", NAME_BUILTIN, username); if (!name) { return NT_STATUS_NO_MEMORY; } status = dcesrv_lsa_lookup_name(ev_ctx, lp_ctx, state, mem_ctx, name, authority_name, sid, rtype, rid); if (NT_STATUS_IS_OK(status)) { return status; } /* OK, I give up - perhaps we need to assume the user is in our domain? */ name = talloc_asprintf(mem_ctx, "%s\\%s", state->domain_name, username); if (!name) { return NT_STATUS_NO_MEMORY; } status = dcesrv_lsa_lookup_name(ev_ctx, lp_ctx, state, mem_ctx, name, authority_name, sid, rtype, rid); if (NT_STATUS_IS_OK(status)) { return status; } return STATUS_SOME_UNMAPPED; } else if (strcasecmp_m(domain, NAME_NT_AUTHORITY) == 0) { if (!*username) { *authority_name = NAME_NT_AUTHORITY; *sid = dom_sid_parse_talloc(mem_ctx, SID_NT_AUTHORITY); *rtype = SID_NAME_DOMAIN; dom_sid_split_rid(NULL, *sid, NULL, rid); return NT_STATUS_OK; } /* Look up table of well known names */ status = lookup_well_known_names(mem_ctx, domain, username, authority_name, sid, rtype); if (NT_STATUS_IS_OK(status)) { dom_sid_split_rid(NULL, *sid, NULL, rid); } return status; } else if (strcasecmp_m(domain, NAME_BUILTIN) == 0) { *authority_name = NAME_BUILTIN; domain_dn = state->builtin_dn; } else if (strcasecmp_m(domain, state->domain_dns) == 0) { *authority_name = state->domain_name; domain_dn = state->domain_dn; } else if (strcasecmp_m(domain, state->domain_name) == 0) { *authority_name = state->domain_name; domain_dn = state->domain_dn; } else { /* Not local, need to ask winbind in future */ return STATUS_SOME_UNMAPPED; } ret = gendb_search_dn(state->sam_ldb, mem_ctx, domain_dn, &res, attrs); if (ret == 1) { domain_sid = samdb_result_dom_sid(mem_ctx, res[0], "objectSid"); if (domain_sid == NULL) { return NT_STATUS_INVALID_SID; } } else { return NT_STATUS_INVALID_SID; } if (!*username) { *sid = domain_sid; *rtype = SID_NAME_DOMAIN; *rid = 0xFFFFFFFF; return NT_STATUS_OK; } ret = gendb_search(state->sam_ldb, mem_ctx, domain_dn, &res, attrs, "(&(sAMAccountName=%s)(objectSid=*))", ldb_binary_encode_string(mem_ctx, username)); if (ret == -1) { return NT_STATUS_INVALID_SID; } for (i=0; i < ret; i++) { *sid = samdb_result_dom_sid(mem_ctx, res[i], "objectSid"); if (*sid == NULL) { return NT_STATUS_INVALID_SID; } /* Check that this is in the domain */ if (!dom_sid_in_domain(domain_sid, *sid)) { continue; } atype = samdb_result_uint(res[i], "sAMAccountType", 0); *rtype = ds_atype_map(atype); if (*rtype == SID_NAME_UNKNOWN) { return STATUS_SOME_UNMAPPED; } dom_sid_split_rid(NULL, *sid, NULL, rid); return NT_STATUS_OK; } /* need to check for an allocated sid */ return NT_STATUS_INVALID_SID; }
/* Printer functions */ static WERROR sptr_EnumPrinters(struct ntptr_context *ntptr, TALLOC_CTX *mem_ctx, struct spoolss_EnumPrinters *r) { struct ldb_context *sptr_db = talloc_get_type(ntptr->private_data, struct ldb_context); struct ldb_message **msgs; int count; int i; union spoolss_PrinterInfo *info; count = sptr_db_search(sptr_db, mem_ctx, NULL, &msgs, NULL, "(&(objectclass=printer))"); if (count == 0) return WERR_OK; if (count < 0) return WERR_GENERAL_FAILURE; info = talloc_array(mem_ctx, union spoolss_PrinterInfo, count); W_ERROR_HAVE_NO_MEMORY(info); switch(r->in.level) { case 1: for (i = 0; i < count; i++) { info[i].info1.flags = samdb_result_uint(msgs[i], "flags", 0); info[i].info1.name = samdb_result_string(msgs[i], "name", ""); W_ERROR_HAVE_NO_MEMORY(info[i].info1.name); info[i].info1.description = samdb_result_string(msgs[i], "description", ""); W_ERROR_HAVE_NO_MEMORY(info[i].info1.description); info[i].info1.comment = samdb_result_string(msgs[i], "comment", NULL); } break; case 2: for (i = 0; i < count; i++) { info[i].info2.servername = samdb_result_string(msgs[i], "servername", ""); W_ERROR_HAVE_NO_MEMORY(info[i].info2.servername); info[i].info2.printername = samdb_result_string(msgs[i], "printername", ""); W_ERROR_HAVE_NO_MEMORY(info[i].info2.printername); info[i].info2.sharename = samdb_result_string(msgs[i], "sharename", ""); W_ERROR_HAVE_NO_MEMORY(info[i].info2.sharename); info[i].info2.portname = samdb_result_string(msgs[i], "portname", ""); W_ERROR_HAVE_NO_MEMORY(info[i].info2.portname); info[i].info2.drivername = samdb_result_string(msgs[i], "drivername", ""); W_ERROR_HAVE_NO_MEMORY(info[i].info2.drivername); info[i].info2.comment = samdb_result_string(msgs[i], "comment", NULL); info[i].info2.location = samdb_result_string(msgs[i], "location", NULL); info[i].info2.devmode = NULL; info[i].info2.sepfile = samdb_result_string(msgs[i], "sepfile", NULL); info[i].info2.printprocessor = samdb_result_string(msgs[i], "printprocessor", ""); W_ERROR_HAVE_NO_MEMORY(info[i].info2.printprocessor); info[i].info2.datatype = samdb_result_string(msgs[i], "datatype", ""); W_ERROR_HAVE_NO_MEMORY(info[i].info2.datatype); info[i].info2.parameters = samdb_result_string(msgs[i], "parameters", NULL); info[i].info2.secdesc = NULL; info[i].info2.attributes = samdb_result_uint(msgs[i], "attributes", 0); info[i].info2.priority = samdb_result_uint(msgs[i], "priority", 0); info[i].info2.defaultpriority = samdb_result_uint(msgs[i], "defaultpriority", 0); info[i].info2.starttime = samdb_result_uint(msgs[i], "starttime", 0); info[i].info2.untiltime = samdb_result_uint(msgs[i], "untiltime", 0); info[i].info2.status = samdb_result_uint(msgs[i], "status", 0); info[i].info2.cjobs = samdb_result_uint(msgs[i], "cjobs", 0); info[i].info2.averageppm = samdb_result_uint(msgs[i], "averageppm", 0); } break; case 4: for (i = 0; i < count; i++) { info[i].info4.printername = samdb_result_string(msgs[i], "printername", ""); W_ERROR_HAVE_NO_MEMORY(info[i].info2.printername); info[i].info4.servername = samdb_result_string(msgs[i], "servername", ""); W_ERROR_HAVE_NO_MEMORY(info[i].info2.servername); info[i].info4.attributes = samdb_result_uint(msgs[i], "attributes", 0); } break; case 5: for (i = 0; i < count; i++) { info[i].info5.printername = samdb_result_string(msgs[i], "name", ""); W_ERROR_HAVE_NO_MEMORY(info[i].info5.printername); info[i].info5.portname = samdb_result_string(msgs[i], "port", ""); W_ERROR_HAVE_NO_MEMORY(info[i].info5.portname); info[i].info5.attributes = samdb_result_uint(msgs[i], "attributes", 0); info[i].info5.device_not_selected_timeout = samdb_result_uint(msgs[i], "device_not_selected_timeout", 0); info[i].info5.transmission_retry_timeout = samdb_result_uint(msgs[i], "transmission_retry_timeout", 0); } break; default: return WERR_UNKNOWN_LEVEL; } *r->out.info = info; *r->out.count = count; return WERR_OK; }
static WERROR sptr_SetPrintServerForm(struct ntptr_GenericHandle *server, TALLOC_CTX *mem_ctx, struct spoolss_SetForm *r) { struct ldb_context *sptr_db = talloc_get_type(server->ntptr->private_data, struct ldb_context); struct ldb_message *msg,**msgs; const char * const attrs[] = { "flags", NULL}; int count, ret; enum spoolss_FormFlags flags; /* TODO: do checks access here * if (!(server->access_mask & desired_access)) { * return WERR_FOOBAR; * } */ switch (r->in.level) { case 1: if (!r->in.info.info1) { return WERR_FOOBAR; } count = sptr_db_search(sptr_db, mem_ctx, ldb_dn_new(mem_ctx, sptr_db, "CN=Forms,CN=PrintServer"), &msgs, attrs, "(&(form-name=%s)(objectClass=form))", r->in.info.info1->form_name); if (count == 0) return WERR_FOOBAR; if (count > 1) return WERR_FOOBAR; if (count < 0) return WERR_GENERAL_FAILURE; flags = samdb_result_uint(msgs[0], "flags", SPOOLSS_FORM_BUILTIN); if (flags != SPOOLSS_FORM_USER) { return WERR_FOOBAR; } msg = ldb_msg_new(mem_ctx); W_ERROR_HAVE_NO_MEMORY(msg); /* add core elements to the ldb_message for the user */ msg->dn = msgs[0]->dn; SET_UINT(sptr_db, msg, "flags", r->in.info.info1->flags); SET_STRING(sptr_db, msg, "form-name", r->in.info.info1->form_name); SET_UINT(sptr_db, msg, "size-width", r->in.info.info1->size.width); SET_UINT(sptr_db, msg, "size-height", r->in.info.info1->size.height); SET_UINT(sptr_db, msg, "area-left", r->in.info.info1->area.left); SET_UINT(sptr_db, msg, "area-top", r->in.info.info1->area.top); SET_UINT(sptr_db, msg, "area-right", r->in.info.info1->area.right); SET_UINT(sptr_db, msg, "area-bottom", r->in.info.info1->area.bottom); break; default: return WERR_UNKNOWN_LEVEL; } ret = samdb_replace(sptr_db, mem_ctx, msg); if (ret != 0) { return WERR_FOOBAR; } return WERR_OK; }