rpc_server/srv_lsa_nt.c

説明を見る。
00001 /*
00002  *  Unix SMB/CIFS implementation.
00003  *  RPC Pipe client / server routines
00004  *  Copyright (C) Andrew Tridgell              1992-1997,
00005  *  Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
00006  *  Copyright (C) Paul Ashton                       1997,
00007  *  Copyright (C) Jeremy Allison                    2001, 2006.
00008  *  Copyright (C) Rafal Szczesniak                  2002,
00009  *  Copyright (C) Jim McDonough <jmcd@us.ibm.com>   2002,
00010  *  Copyright (C) Simo Sorce                        2003.
00011  *  Copyright (C) Gerald (Jerry) Carter             2005.
00012  *  Copyright (C) Volker Lendecke                   2005.
00013  *
00014  *  This program is free software; you can redistribute it and/or modify
00015  *  it under the terms of the GNU General Public License as published by
00016  *  the Free Software Foundation; either version 2 of the License, or
00017  *  (at your option) any later version.
00018  *  
00019  *  This program is distributed in the hope that it will be useful,
00020  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00021  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00022  *  GNU General Public License for more details.
00023  *  
00024  *  You should have received a copy of the GNU General Public License
00025  *  along with this program; if not, write to the Free Software
00026  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00027  */
00028 
00029 /* This is the implementation of the lsa server code. */
00030 
00031 #include "includes.h"
00032 
00033 #undef DBGC_CLASS
00034 #define DBGC_CLASS DBGC_RPC_SRV
00035 
00036 extern PRIVS privs[];
00037 
00038 struct lsa_info {
00039         DOM_SID sid;
00040         uint32 access;
00041 };
00042 
00043 struct generic_mapping lsa_generic_mapping = {
00044         POLICY_READ,
00045         POLICY_WRITE,
00046         POLICY_EXECUTE,
00047         POLICY_ALL_ACCESS
00048 };
00049 
00050 /*******************************************************************
00051  Function to free the per handle data.
00052  ********************************************************************/
00053 
00054 static void free_lsa_info(void *ptr)
00055 {
00056         struct lsa_info *lsa = (struct lsa_info *)ptr;
00057 
00058         SAFE_FREE(lsa);
00059 }
00060 
00061 /***************************************************************************
00062 Init dom_query
00063  ***************************************************************************/
00064 
00065 static void init_dom_query_3(DOM_QUERY_3 *d_q, const char *dom_name, DOM_SID *dom_sid)
00066 {
00067         d_q->buffer_dom_name = (dom_name != NULL) ? 1 : 0; /* domain buffer pointer */
00068         d_q->buffer_dom_sid = (dom_sid != NULL) ? 1 : 0;  /* domain sid pointer */
00069 
00070         /* this string is supposed to be non-null terminated. */
00071         /* But the maxlen in this UNISTR2 must include the terminating null. */
00072         init_unistr2(&d_q->uni_domain_name, dom_name, UNI_BROKEN_NON_NULL);
00073 
00074         /*
00075          * I'm not sure why this really odd combination of length
00076          * values works, but it does appear to. I need to look at
00077          * this *much* more closely - but at the moment leave alone
00078          * until it's understood. This allows a W2k client to join
00079          * a domain with both odd and even length names... JRA.
00080          */
00081 
00082         /*
00083          * IMPORTANT NOTE !!!!
00084          * The two fields below probably are reversed in meaning, ie.
00085          * the first field is probably the str_len, the second the max
00086          * len. Both are measured in bytes anyway.
00087          */
00088 
00089         d_q->uni_dom_str_len = d_q->uni_domain_name.uni_max_len * 2;
00090         d_q->uni_dom_max_len = d_q->uni_domain_name.uni_str_len * 2;
00091 
00092         if (dom_sid != NULL)
00093                 init_dom_sid2(&d_q->dom_sid, dom_sid);
00094 }
00095 
00096 /***************************************************************************
00097 Init dom_query
00098  ***************************************************************************/
00099 
00100 static void init_dom_query_5(DOM_QUERY_5 *d_q, const char *dom_name, DOM_SID *dom_sid)
00101 {
00102         init_dom_query_3(d_q, dom_name, dom_sid);
00103 }
00104 
00105 /***************************************************************************
00106  init_dom_ref - adds a domain if it's not already in, returns the index.
00107 ***************************************************************************/
00108 
00109 static int init_dom_ref(DOM_R_REF *ref, const char *dom_name, DOM_SID *dom_sid)
00110 {
00111         int num = 0;
00112 
00113         if (dom_name != NULL) {
00114                 for (num = 0; num < ref->num_ref_doms_1; num++) {
00115                         if (sid_equal(dom_sid, &ref->ref_dom[num].ref_dom.sid))
00116                                 return num;
00117                 }
00118         } else {
00119                 num = ref->num_ref_doms_1;
00120         }
00121 
00122         if (num >= MAX_REF_DOMAINS) {
00123                 /* index not found, already at maximum domain limit */
00124                 return -1;
00125         }
00126 
00127         ref->num_ref_doms_1 = num+1;
00128         ref->ptr_ref_dom  = 1;
00129         ref->max_entries = MAX_REF_DOMAINS;
00130         ref->num_ref_doms_2 = num+1;
00131 
00132         ref->hdr_ref_dom[num].ptr_dom_sid = 1; /* dom sid cannot be NULL. */
00133 
00134         init_unistr2(&ref->ref_dom[num].uni_dom_name, dom_name, UNI_FLAGS_NONE);
00135         init_uni_hdr(&ref->hdr_ref_dom[num].hdr_dom_name, &ref->ref_dom[num].uni_dom_name);
00136 
00137         init_dom_sid2(&ref->ref_dom[num].ref_dom, dom_sid );
00138 
00139         return num;
00140 }
00141 
00142 /***************************************************************************
00143  lookup_lsa_rids. Must be called as root for lookup_name to work.
00144  ***************************************************************************/
00145 
00146 static NTSTATUS lookup_lsa_rids(TALLOC_CTX *mem_ctx,
00147                         DOM_R_REF *ref,
00148                         DOM_RID *prid,
00149                         uint32 num_entries,
00150                         const UNISTR2 *name,
00151                         int flags,
00152                         uint32 *pmapped_count)
00153 {
00154         uint32 mapped_count, i;
00155 
00156         SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
00157 
00158         mapped_count = 0;
00159         *pmapped_count = 0;
00160 
00161         for (i = 0; i < num_entries; i++) {
00162                 DOM_SID sid;
00163                 uint32 rid;
00164                 int dom_idx;
00165                 char *full_name;
00166                 const char *domain;
00167                 enum lsa_SidType type = SID_NAME_UNKNOWN;
00168 
00169                 /* Split name into domain and user component */
00170 
00171                 full_name = rpcstr_pull_unistr2_talloc(mem_ctx, &name[i]);
00172                 if (full_name == NULL) {
00173                         DEBUG(0, ("pull_ucs2_talloc failed\n"));
00174                         return NT_STATUS_NO_MEMORY;
00175                 }
00176 
00177                 DEBUG(5, ("lookup_lsa_rids: looking up name %s\n", full_name));
00178 
00179                 /* We can ignore the result of lookup_name, it will not touch
00180                    "type" if it's not successful */
00181 
00182                 lookup_name(mem_ctx, full_name, flags, &domain, NULL,
00183                             &sid, &type);
00184 
00185                 switch (type) {
00186                 case SID_NAME_USER:
00187                 case SID_NAME_DOM_GRP:
00188                 case SID_NAME_DOMAIN:
00189                 case SID_NAME_ALIAS:
00190                 case SID_NAME_WKN_GRP:
00191                         DEBUG(5, ("init_lsa_rids: %s found\n", full_name));
00192                         /* Leave these unchanged */
00193                         break;
00194                 default:
00195                         /* Don't hand out anything but the list above */
00196                         DEBUG(5, ("init_lsa_rids: %s not found\n", full_name));
00197                         type = SID_NAME_UNKNOWN;
00198                         break;
00199                 }
00200 
00201                 rid = 0;
00202                 dom_idx = -1;
00203 
00204                 if (type != SID_NAME_UNKNOWN) {
00205                         sid_split_rid(&sid, &rid);
00206                         dom_idx = init_dom_ref(ref, domain, &sid);
00207                         mapped_count++;
00208                 }
00209 
00210                 init_dom_rid(&prid[i], rid, type, dom_idx);
00211         }
00212 
00213         *pmapped_count = mapped_count;
00214         return NT_STATUS_OK;
00215 }
00216 
00217 /***************************************************************************
00218  lookup_lsa_sids. Must be called as root for lookup_name to work.
00219  ***************************************************************************/
00220 
00221 static NTSTATUS lookup_lsa_sids(TALLOC_CTX *mem_ctx,
00222                         DOM_R_REF *ref,
00223                         LSA_TRANSLATED_SID3 *trans_sids,
00224                         uint32 num_entries,
00225                         const UNISTR2 *name,
00226                         int flags,
00227                         uint32 *pmapped_count)
00228 {
00229         uint32 mapped_count, i;
00230 
00231         SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
00232 
00233         mapped_count = 0;
00234         *pmapped_count = 0;
00235 
00236         for (i = 0; i < num_entries; i++) {
00237                 DOM_SID sid;
00238                 uint32 rid;
00239                 int dom_idx;
00240                 char *full_name;
00241                 const char *domain;
00242                 enum lsa_SidType type = SID_NAME_UNKNOWN;
00243 
00244                 /* Split name into domain and user component */
00245 
00246                 full_name = rpcstr_pull_unistr2_talloc(mem_ctx, &name[i]);
00247                 if (full_name == NULL) {
00248                         DEBUG(0, ("pull_ucs2_talloc failed\n"));
00249                         return NT_STATUS_NO_MEMORY;
00250                 }
00251 
00252                 DEBUG(5, ("init_lsa_sids: looking up name %s\n", full_name));
00253 
00254                 /* We can ignore the result of lookup_name, it will not touch
00255                    "type" if it's not successful */
00256 
00257                 lookup_name(mem_ctx, full_name, flags, &domain, NULL,
00258                             &sid, &type);
00259 
00260                 switch (type) {
00261                 case SID_NAME_USER:
00262                 case SID_NAME_DOM_GRP:
00263                 case SID_NAME_DOMAIN:
00264                 case SID_NAME_ALIAS:
00265                 case SID_NAME_WKN_GRP:
00266                         DEBUG(5, ("init_lsa_sids: %s found\n", full_name));
00267                         /* Leave these unchanged */
00268                         break;
00269                 default:
00270                         /* Don't hand out anything but the list above */
00271                         DEBUG(5, ("init_lsa_sids: %s not found\n", full_name));
00272                         type = SID_NAME_UNKNOWN;
00273                         break;
00274                 }
00275 
00276                 rid = 0;
00277                 dom_idx = -1;
00278 
00279                 if (type != SID_NAME_UNKNOWN) {
00280                         DOM_SID domain_sid;
00281                         sid_copy(&domain_sid, &sid);
00282                         sid_split_rid(&domain_sid, &rid);
00283                         dom_idx = init_dom_ref(ref, domain, &domain_sid);
00284                         mapped_count++;
00285                 }
00286 
00287                 /* Initialize the LSA_TRANSLATED_SID3 return. */
00288                 trans_sids[i].sid_type = type;
00289                 trans_sids[i].sid2 = TALLOC_P(mem_ctx, DOM_SID2);
00290                 if (trans_sids[i].sid2 == NULL) {
00291                         return NT_STATUS_NO_MEMORY;
00292                 }
00293                 init_dom_sid2(trans_sids[i].sid2, &sid);
00294                 trans_sids[i].sid_idx = dom_idx;
00295         }
00296 
00297         *pmapped_count = mapped_count;
00298         return NT_STATUS_OK;
00299 }
00300 
00301 /***************************************************************************
00302  init_reply_lookup_names
00303  ***************************************************************************/
00304 
00305 static void init_reply_lookup_names(LSA_R_LOOKUP_NAMES *r_l,
00306                 DOM_R_REF *ref, uint32 num_entries,
00307                 DOM_RID *rid, uint32 mapped_count)
00308 {
00309         r_l->ptr_dom_ref  = 1;
00310         r_l->dom_ref      = ref;
00311 
00312         r_l->num_entries  = num_entries;
00313         r_l->ptr_entries  = 1;
00314         r_l->num_entries2 = num_entries;
00315         r_l->dom_rid      = rid;
00316 
00317         r_l->mapped_count = mapped_count;
00318 }
00319 
00320 /***************************************************************************
00321  init_reply_lookup_names2
00322  ***************************************************************************/
00323 
00324 static void init_reply_lookup_names2(LSA_R_LOOKUP_NAMES2 *r_l,
00325                 DOM_R_REF *ref, uint32 num_entries,
00326                 DOM_RID2 *rid, uint32 mapped_count)
00327 {
00328         r_l->ptr_dom_ref  = 1;
00329         r_l->dom_ref      = ref;
00330 
00331         r_l->num_entries  = num_entries;
00332         r_l->ptr_entries  = 1;
00333         r_l->num_entries2 = num_entries;
00334         r_l->dom_rid      = rid;
00335 
00336         r_l->mapped_count = mapped_count;
00337 }
00338 
00339 /***************************************************************************
00340  init_reply_lookup_names3
00341  ***************************************************************************/
00342 
00343 static void init_reply_lookup_names3(LSA_R_LOOKUP_NAMES3 *r_l,
00344                 DOM_R_REF *ref, uint32 num_entries,
00345                 LSA_TRANSLATED_SID3 *trans_sids, uint32 mapped_count)
00346 {
00347         r_l->ptr_dom_ref  = 1;
00348         r_l->dom_ref      = ref;
00349 
00350         r_l->num_entries  = num_entries;
00351         r_l->ptr_entries  = 1;
00352         r_l->num_entries2 = num_entries;
00353         r_l->trans_sids   = trans_sids;
00354 
00355         r_l->mapped_count = mapped_count;
00356 }
00357 
00358 /***************************************************************************
00359  init_reply_lookup_names4
00360  ***************************************************************************/
00361 
00362 static void init_reply_lookup_names4(LSA_R_LOOKUP_NAMES4 *r_l,
00363                 DOM_R_REF *ref, uint32 num_entries,
00364                 LSA_TRANSLATED_SID3 *trans_sids, uint32 mapped_count)
00365 {
00366         r_l->ptr_dom_ref  = 1;
00367         r_l->dom_ref      = ref;
00368 
00369         r_l->num_entries  = num_entries;
00370         r_l->ptr_entries  = 1;
00371         r_l->num_entries2 = num_entries;
00372         r_l->trans_sids   = trans_sids;
00373 
00374         r_l->mapped_count = mapped_count;
00375 }
00376 
00377 /***************************************************************************
00378  Init_reply_lookup_sids.
00379  ***************************************************************************/
00380 
00381 static void init_reply_lookup_sids2(LSA_R_LOOKUP_SIDS2 *r_l,
00382                                 DOM_R_REF *ref,
00383                                 uint32 mapped_count)
00384 {
00385         r_l->ptr_dom_ref  = ref ? 1 : 0;
00386         r_l->dom_ref      = ref;
00387         r_l->mapped_count = mapped_count;
00388 }
00389 
00390 /***************************************************************************
00391  Init_reply_lookup_sids.
00392  ***************************************************************************/
00393 
00394 static void init_reply_lookup_sids3(LSA_R_LOOKUP_SIDS3 *r_l,
00395                                 DOM_R_REF *ref,
00396                                 uint32 mapped_count)
00397 {
00398         r_l->ptr_dom_ref  = ref ? 1 : 0;
00399         r_l->dom_ref      = ref;
00400         r_l->mapped_count = mapped_count;
00401 }
00402 
00403 /***************************************************************************
00404  Init_reply_lookup_sids.
00405  ***************************************************************************/
00406 
00407 static NTSTATUS init_reply_lookup_sids(TALLOC_CTX *mem_ctx,
00408                                 LSA_R_LOOKUP_SIDS *r_l,
00409                                 DOM_R_REF *ref,
00410                                 LSA_TRANS_NAME_ENUM2 *names,
00411                                 uint32 mapped_count)
00412 {
00413         LSA_TRANS_NAME_ENUM *oldnames = &r_l->names;
00414 
00415         oldnames->num_entries = names->num_entries;
00416         oldnames->ptr_trans_names = names->ptr_trans_names;
00417         oldnames->num_entries2 = names->num_entries2;
00418         oldnames->uni_name = names->uni_name;
00419 
00420         if (names->num_entries) {
00421                 int i;
00422 
00423                 oldnames->name = TALLOC_ARRAY(mem_ctx, LSA_TRANS_NAME, names->num_entries);
00424 
00425                 if (!oldnames->name) {
00426                         return NT_STATUS_NO_MEMORY;
00427                 }
00428                 for (i = 0; i < names->num_entries; i++) {
00429                         oldnames->name[i].sid_name_use = names->name[i].sid_name_use;
00430                         oldnames->name[i].hdr_name = names->name[i].hdr_name;
00431                         oldnames->name[i].domain_idx = names->name[i].domain_idx;
00432                 }
00433         }
00434 
00435         r_l->ptr_dom_ref  = ref ? 1 : 0;
00436         r_l->dom_ref      = ref;
00437         r_l->mapped_count = mapped_count;
00438         return NT_STATUS_OK;
00439 }
00440 
00441 static NTSTATUS lsa_get_generic_sd(TALLOC_CTX *mem_ctx, SEC_DESC **sd, size_t *sd_size)
00442 {
00443         DOM_SID local_adm_sid;
00444         DOM_SID adm_sid;
00445 
00446         SEC_ACE ace[3];
00447         SEC_ACCESS mask;
00448 
00449         SEC_ACL *psa = NULL;
00450 
00451         init_sec_access(&mask, POLICY_EXECUTE);
00452         init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
00453 
00454         sid_copy(&adm_sid, get_global_sam_sid());
00455         sid_append_rid(&adm_sid, DOMAIN_GROUP_RID_ADMINS);
00456         init_sec_access(&mask, POLICY_ALL_ACCESS);
00457         init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
00458 
00459         sid_copy(&local_adm_sid, &global_sid_Builtin);
00460         sid_append_rid(&local_adm_sid, BUILTIN_ALIAS_RID_ADMINS);
00461         init_sec_access(&mask, POLICY_ALL_ACCESS);
00462         init_sec_ace(&ace[2], &local_adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
00463 
00464         if((psa = make_sec_acl(mem_ctx, NT4_ACL_REVISION, 3, ace)) == NULL)
00465                 return NT_STATUS_NO_MEMORY;
00466 
00467         if((*sd = make_sec_desc(mem_ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, &adm_sid, NULL, NULL, psa, sd_size)) == NULL)
00468                 return NT_STATUS_NO_MEMORY;
00469 
00470         return NT_STATUS_OK;
00471 }
00472 
00473 #if 0   /* AD DC work in ongoing in Samba 4 */
00474 
00475 /***************************************************************************
00476  Init_dns_dom_info.
00477 ***************************************************************************/
00478 
00479 static void init_dns_dom_info(LSA_DNS_DOM_INFO *r_l, const char *nb_name,
00480                               const char *dns_name, const char *forest_name,
00481                               struct GUID *dom_guid, DOM_SID *dom_sid)
00482 {
00483         if (nb_name && *nb_name) {
00484                 init_unistr2(&r_l->uni_nb_dom_name, nb_name, UNI_FLAGS_NONE);
00485                 init_uni_hdr(&r_l->hdr_nb_dom_name, &r_l->uni_nb_dom_name);
00486                 r_l->hdr_nb_dom_name.uni_max_len += 2;
00487                 r_l->uni_nb_dom_name.uni_max_len += 1;
00488         }
00489         
00490         if (dns_name && *dns_name) {
00491                 init_unistr2(&r_l->uni_dns_dom_name, dns_name, UNI_FLAGS_NONE);
00492                 init_uni_hdr(&r_l->hdr_dns_dom_name, &r_l->uni_dns_dom_name);
00493                 r_l->hdr_dns_dom_name.uni_max_len += 2;
00494                 r_l->uni_dns_dom_name.uni_max_len += 1;
00495         }
00496 
00497         if (forest_name && *forest_name) {
00498                 init_unistr2(&r_l->uni_forest_name, forest_name, UNI_FLAGS_NONE);
00499                 init_uni_hdr(&r_l->hdr_forest_name, &r_l->uni_forest_name);
00500                 r_l->hdr_forest_name.uni_max_len += 2;
00501                 r_l->uni_forest_name.uni_max_len += 1;
00502         }
00503 
00504         /* how do we init the guid ? probably should write an init fn */
00505         if (dom_guid) {
00506                 memcpy(&r_l->dom_guid, dom_guid, sizeof(struct GUID));
00507         }
00508         
00509         if (dom_sid) {
00510                 r_l->ptr_dom_sid = 1;
00511                 init_dom_sid2(&r_l->dom_sid, dom_sid);
00512         }
00513 }
00514 #endif  /* AD DC work in ongoing in Samba 4 */
00515 
00516 
00517 /***************************************************************************
00518  _lsa_open_policy2.
00519  ***************************************************************************/
00520 
00521 NTSTATUS _lsa_open_policy2(pipes_struct *p, LSA_Q_OPEN_POL2 *q_u, LSA_R_OPEN_POL2 *r_u)
00522 {
00523         struct lsa_info *info;
00524         SEC_DESC *psd = NULL;
00525         size_t sd_size;
00526         uint32 des_access=q_u->des_access;
00527         uint32 acc_granted;
00528         NTSTATUS status;
00529 
00530 
00531         /* map the generic bits to the lsa policy ones */
00532         se_map_generic(&des_access, &lsa_generic_mapping);
00533 
00534         /* get the generic lsa policy SD until we store it */
00535         lsa_get_generic_sd(p->mem_ctx, &psd, &sd_size);
00536 
00537         if(!se_access_check(psd, p->pipe_user.nt_user_token, des_access, &acc_granted, &status)) {
00538                 if (geteuid() != 0) {
00539                         return status;
00540                 }
00541                 DEBUG(4,("ACCESS should be DENIED (granted: %#010x;  required: %#010x)\n",
00542                          acc_granted, des_access));
00543                 DEBUGADD(4,("but overwritten by euid == 0\n"));
00544         }
00545 
00546         /* This is needed for lsa_open_account and rpcclient .... :-) */
00547 
00548         if (geteuid() == 0)
00549                 acc_granted = POLICY_ALL_ACCESS;
00550 
00551         /* associate the domain SID with the (unique) handle. */
00552         if ((info = SMB_MALLOC_P(struct lsa_info)) == NULL)
00553                 return NT_STATUS_NO_MEMORY;
00554 
00555         ZERO_STRUCTP(info);
00556         sid_copy(&info->sid,get_global_sam_sid());
00557         info->access = acc_granted;
00558 
00559         /* set up the LSA QUERY INFO response */
00560         if (!create_policy_hnd(p, &r_u->pol, free_lsa_info, (void *)info))
00561                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
00562 
00563         return NT_STATUS_OK;
00564 }
00565 
00566 /***************************************************************************
00567  _lsa_open_policy
00568  ***************************************************************************/
00569 
00570 NTSTATUS _lsa_open_policy(pipes_struct *p, LSA_Q_OPEN_POL *q_u, LSA_R_OPEN_POL *r_u)
00571 {
00572         struct lsa_info *info;
00573         SEC_DESC *psd = NULL;
00574         size_t sd_size;
00575         uint32 des_access=q_u->des_access;
00576         uint32 acc_granted;
00577         NTSTATUS status;
00578 
00579 
00580         /* map the generic bits to the lsa policy ones */
00581         se_map_generic(&des_access, &lsa_generic_mapping);
00582 
00583         /* get the generic lsa policy SD until we store it */
00584         lsa_get_generic_sd(p->mem_ctx, &psd, &sd_size);
00585 
00586         if(!se_access_check(psd, p->pipe_user.nt_user_token, des_access, &acc_granted, &status)) {
00587                 if (geteuid() != 0) {
00588                         return status;
00589                 }
00590                 DEBUG(4,("ACCESS should be DENIED (granted: %#010x;  required: %#010x)\n",
00591                          acc_granted, des_access));
00592                 DEBUGADD(4,("but overwritten by euid == 0\n"));
00593                 acc_granted = des_access;
00594         }
00595 
00596         /* associate the domain SID with the (unique) handle. */
00597         if ((info = SMB_MALLOC_P(struct lsa_info)) == NULL)
00598                 return NT_STATUS_NO_MEMORY;
00599 
00600         ZERO_STRUCTP(info);
00601         sid_copy(&info->sid,get_global_sam_sid());
00602         info->access = acc_granted;
00603 
00604         /* set up the LSA QUERY INFO response */
00605         if (!create_policy_hnd(p, &r_u->pol, free_lsa_info, (void *)info))
00606                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
00607 
00608         return NT_STATUS_OK;
00609 }
00610 
00611 /***************************************************************************
00612  _lsa_enum_trust_dom - this needs fixing to do more than return NULL ! JRA.
00613  ufff, done :)  mimir
00614  ***************************************************************************/
00615 
00616 NTSTATUS _lsa_enum_trust_dom(pipes_struct *p, LSA_Q_ENUM_TRUST_DOM *q_u,
00617                              LSA_R_ENUM_TRUST_DOM *r_u)
00618 {
00619         struct lsa_info *info;
00620         uint32 next_idx;
00621         struct trustdom_info **domains;
00622 
00623         /*
00624          * preferred length is set to 5 as a "our" preferred length
00625          * nt sets this parameter to 2
00626          * update (20.08.2002): it's not preferred length, but preferred size!
00627          * it needs further investigation how to optimally choose this value
00628          */
00629         uint32 max_num_domains =
00630                 q_u->preferred_len < 5 ? q_u->preferred_len : 10;
00631         uint32 num_domains;
00632         NTSTATUS nt_status;
00633         uint32 num_thistime;
00634 
00635         if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info))
00636                 return NT_STATUS_INVALID_HANDLE;
00637 
00638         /* check if the user have enough rights */
00639         if (!(info->access & POLICY_VIEW_LOCAL_INFORMATION))
00640                 return NT_STATUS_ACCESS_DENIED;
00641 
00642         nt_status = secrets_trusted_domains(p->mem_ctx, &num_domains,
00643                                             &domains);
00644 
00645         if (!NT_STATUS_IS_OK(nt_status)) {
00646                 return nt_status;
00647         }
00648 
00649         if (q_u->enum_context < num_domains) {
00650                 num_thistime = MIN(num_domains, max_num_domains);
00651 
00652                 r_u->status = STATUS_MORE_ENTRIES;
00653 
00654                 if (q_u->enum_context + num_thistime > num_domains) {
00655                         num_thistime = num_domains - q_u->enum_context;
00656                         r_u->status = NT_STATUS_OK;
00657                 }
00658 
00659                 next_idx = q_u->enum_context + num_thistime;
00660         } else {
00661                 num_thistime = 0;
00662                 next_idx = 0xffffffff;
00663                 r_u->status = NT_STATUS_NO_MORE_ENTRIES;
00664         }
00665                 
00666         /* set up the lsa_enum_trust_dom response */
00667 
00668         init_r_enum_trust_dom(p->mem_ctx, r_u, next_idx,
00669                               num_thistime, domains+q_u->enum_context);
00670 
00671         return r_u->status;
00672 }
00673 
00674 /***************************************************************************
00675  _lsa_query_info. See the POLICY_INFOMATION_CLASS docs at msdn.
00676  ***************************************************************************/
00677 
00678 NTSTATUS _lsa_query_info(pipes_struct *p, LSA_Q_QUERY_INFO *q_u, LSA_R_QUERY_INFO *r_u)
00679 {
00680         struct lsa_info *handle;
00681         LSA_INFO_CTR *ctr = &r_u->ctr;
00682         DOM_SID domain_sid;
00683         const char *name;
00684         DOM_SID *sid = NULL;
00685 
00686         r_u->status = NT_STATUS_OK;
00687 
00688         if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&handle))
00689                 return NT_STATUS_INVALID_HANDLE;
00690 
00691         switch (q_u->info_class) {
00692         case 0x02:
00693                 {
00694 
00695                 uint32 policy_def = LSA_AUDIT_POLICY_ALL;
00696                 
00697                 /* check if the user have enough rights */
00698                 if (!(handle->access & POLICY_VIEW_AUDIT_INFORMATION)) {
00699                         DEBUG(10,("_lsa_query_info: insufficient access rights\n"));
00700                         return NT_STATUS_ACCESS_DENIED;
00701                 }
00702 
00703                 /* fake info: We audit everything. ;) */
00704                 ctr->info.id2.ptr = 1;
00705                 ctr->info.id2.auditing_enabled = True;
00706                 ctr->info.id2.count1 = ctr->info.id2.count2 = LSA_AUDIT_NUM_CATEGORIES;
00707 
00708                 if ((ctr->info.id2.auditsettings = TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, LSA_AUDIT_NUM_CATEGORIES)) == NULL)
00709                         return NT_STATUS_NO_MEMORY;
00710 
00711                 ctr->info.id2.auditsettings[LSA_AUDIT_CATEGORY_ACCOUNT_MANAGEMENT] = policy_def;
00712                 ctr->info.id2.auditsettings[LSA_AUDIT_CATEGORY_FILE_AND_OBJECT_ACCESS] = policy_def; 
00713                 ctr->info.id2.auditsettings[LSA_AUDIT_CATEGORY_LOGON] = policy_def; 
00714                 ctr->info.id2.auditsettings[LSA_AUDIT_CATEGORY_PROCCESS_TRACKING] = policy_def; 
00715                 ctr->info.id2.auditsettings[LSA_AUDIT_CATEGORY_SECURITY_POLICY_CHANGES] = policy_def;
00716                 ctr->info.id2.auditsettings[LSA_AUDIT_CATEGORY_SYSTEM] = policy_def;
00717                 ctr->info.id2.auditsettings[LSA_AUDIT_CATEGORY_USE_OF_USER_RIGHTS] = policy_def; 
00718 
00719                 break;
00720                 }
00721         case 0x03:
00722                 /* check if the user have enough rights */
00723                 if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION))
00724                         return NT_STATUS_ACCESS_DENIED;
00725 
00726                 /* Request PolicyPrimaryDomainInformation. */
00727                 switch (lp_server_role()) {
00728                         case ROLE_DOMAIN_PDC:
00729                         case ROLE_DOMAIN_BDC:
00730                                 name = get_global_sam_name();
00731                                 sid = get_global_sam_sid();
00732                                 break;
00733                         case ROLE_DOMAIN_MEMBER:
00734                                 name = lp_workgroup();
00735                                 /* We need to return the Domain SID here. */
00736                                 if (secrets_fetch_domain_sid(lp_workgroup(), &domain_sid))
00737                                         sid = &domain_sid;
00738                                 else
00739                                         return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
00740                                 break;
00741                         case ROLE_STANDALONE:
00742                                 name = lp_workgroup();
00743                                 sid = NULL;
00744                                 break;
00745                         default:
00746                                 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
00747                 }
00748                 init_dom_query_3(&r_u->ctr.info.id3, name, sid);
00749                 break;
00750         case 0x05:
00751                 /* check if the user have enough rights */
00752                 if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION))
00753                         return NT_STATUS_ACCESS_DENIED;
00754 
00755                 /* Request PolicyAccountDomainInformation. */
00756                 name = get_global_sam_name();
00757                 sid = get_global_sam_sid();
00758                 init_dom_query_5(&r_u->ctr.info.id5, name, sid);
00759                 break;
00760         case 0x06:
00761                 /* check if the user have enough rights */
00762                 if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION))
00763                         return NT_STATUS_ACCESS_DENIED;
00764 
00765                 switch (lp_server_role()) {
00766                         case ROLE_DOMAIN_BDC:
00767                                 /*
00768                                  * only a BDC is a backup controller
00769                                  * of the domain, it controls.
00770                                  */
00771                                 ctr->info.id6.server_role = 2;
00772                                 break;
00773                         default:
00774                                 /*
00775                                  * any other role is a primary
00776                                  * of the domain, it controls.
00777                                  */
00778                                 ctr->info.id6.server_role = 3;
00779                                 break; 
00780                 }
00781                 break;
00782         default:
00783                 DEBUG(0,("_lsa_query_info: unknown info level in Lsa Query: %d\n", q_u->info_class));
00784                 r_u->status = NT_STATUS_INVALID_INFO_CLASS;
00785                 break;
00786         }
00787 
00788         if (NT_STATUS_IS_OK(r_u->status)) {
00789                 r_u->dom_ptr = 0x22000000; /* bizarre */
00790                 ctr->info_class = q_u->info_class;
00791         }
00792 
00793         return r_u->status;
00794 }
00795 
00796 /***************************************************************************
00797  _lsa_lookup_sids_internal
00798  ***************************************************************************/
00799 
00800 static NTSTATUS _lsa_lookup_sids_internal(pipes_struct *p,
00801                                 uint16 level,                           /* input */
00802                                 int num_sids,                           /* input */
00803                                 const DOM_SID2 *sid,                    /* input */
00804                                 DOM_R_REF **pp_ref,                     /* output */
00805                                 LSA_TRANS_NAME_ENUM2 *names,            /* input/output */
00806                                 uint32 *pp_mapped_count)
00807 {
00808         NTSTATUS status;
00809         int i;
00810         const DOM_SID **sids = NULL;
00811         DOM_R_REF *ref = NULL;
00812         uint32 mapped_count = 0;
00813         struct lsa_dom_info *dom_infos = NULL;
00814         struct lsa_name_info *name_infos = NULL;
00815 
00816         *pp_mapped_count = 0;
00817         *pp_ref = NULL;
00818         ZERO_STRUCTP(names);
00819 
00820         if (num_sids == 0) {
00821                 return NT_STATUS_OK;
00822         }
00823 
00824         sids = TALLOC_ARRAY(p->mem_ctx, const DOM_SID *, num_sids);
00825         ref = TALLOC_ZERO_P(p->mem_ctx, DOM_R_REF);
00826 
00827         if (sids == NULL || ref == NULL) {
00828                 return NT_STATUS_NO_MEMORY;
00829         }
00830 
00831         for (i=0; i<num_sids; i++) {
00832                 sids[i] = &sid[i].sid;
00833         }
00834 
00835         status = lookup_sids(p->mem_ctx, num_sids, sids, level,
00836                                   &dom_infos, &name_infos);
00837 
00838         if (!NT_STATUS_IS_OK(status)) {
00839                 return status;
00840         }
00841 
00842         names->name = TALLOC_ARRAY(p->mem_ctx, LSA_TRANS_NAME2, num_sids);
00843         names->uni_name = TALLOC_ARRAY(p->mem_ctx, UNISTR2, num_sids);
00844         if ((names->name == NULL) || (names->uni_name == NULL)) {
00845                 return NT_STATUS_NO_MEMORY;
00846         }
00847 
00848         for (i=0; i<MAX_REF_DOMAINS; i++) {
00849 
00850                 if (!dom_infos[i].valid) {
00851                         break;
00852                 }
00853 
00854                 if (init_dom_ref(ref, dom_infos[i].name,
00855                                  &dom_infos[i].sid) != i) {
00856                         DEBUG(0, ("Domain %s mentioned twice??\n",
00857                                   dom_infos[i].name));
00858                         return NT_STATUS_INTERNAL_ERROR;
00859                 }
00860         }
00861 
00862         for (i=0; i<num_sids; i++) {
00863                 struct lsa_name_info *name = &name_infos[i];
00864 
00865                 if (name->type == SID_NAME_UNKNOWN) {
00866                         name->dom_idx = -1;
00867                         /* unknown sids should return the string representation of the SID */
00868                         name->name = talloc_asprintf(p->mem_ctx, "%s", 
00869                                                      sid_string_static(sids[i]));
00870                         if (name->name == NULL) {
00871                                 return NT_STATUS_NO_MEMORY;
00872                         }
00873                 } else {
00874                         mapped_count += 1;
00875                 }
00876                 init_lsa_trans_name2(&names->name[i], &names->uni_name[i],
00877                                     name->type, name->name, name->dom_idx);
00878         }
00879 
00880         names->num_entries = num_sids;
00881         names->ptr_trans_names = 1;
00882         names->num_entries2 = num_sids;
00883 
00884         status = NT_STATUS_NONE_MAPPED;
00885         if (mapped_count > 0) {
00886                 status = (mapped_count < num_sids) ?
00887                         STATUS_SOME_UNMAPPED : NT_STATUS_OK;
00888         }
00889 
00890         DEBUG(10, ("num_sids %d, mapped_count %d, status %s\n",
00891                    num_sids, mapped_count, nt_errstr(status)));
00892 
00893         *pp_mapped_count = mapped_count;
00894         *pp_ref = ref;
00895 
00896         return status;
00897 }
00898 
00899 /***************************************************************************
00900  _lsa_lookup_sids
00901  ***************************************************************************/
00902 
00903 NTSTATUS _lsa_lookup_sids(pipes_struct *p,
00904                           LSA_Q_LOOKUP_SIDS *q_u,
00905                           LSA_R_LOOKUP_SIDS *r_u)
00906 {
00907         struct lsa_info *handle;
00908         int num_sids = q_u->sids.num_entries;
00909         uint32 mapped_count = 0;
00910         DOM_R_REF *ref = NULL;
00911         LSA_TRANS_NAME_ENUM2 names;
00912         NTSTATUS status;
00913 
00914         if ((q_u->level < 1) || (q_u->level > 6)) {
00915                 return NT_STATUS_INVALID_PARAMETER;
00916         }
00917 
00918         if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&handle)) {
00919                 return NT_STATUS_INVALID_HANDLE;
00920         }
00921 
00922         /* check if the user has enough rights */
00923         if (!(handle->access & POLICY_LOOKUP_NAMES)) {
00924                 return NT_STATUS_ACCESS_DENIED;
00925         }
00926 
00927         if (num_sids >  MAX_LOOKUP_SIDS) {
00928                 DEBUG(5,("_lsa_lookup_sids: limit of %d exceeded, requested %d\n",
00929                          MAX_LOOKUP_SIDS, num_sids));
00930                 return NT_STATUS_NONE_MAPPED;
00931         }
00932 
00933         r_u->status = _lsa_lookup_sids_internal(p,
00934                                                 q_u->level,
00935                                                 num_sids, 
00936                                                 q_u->sids.sid,
00937                                                 &ref,
00938                                                 &names,
00939                                                 &mapped_count);
00940 
00941         /* Convert from LSA_TRANS_NAME_ENUM2 to LSA_TRANS_NAME_ENUM */
00942 
00943         status = init_reply_lookup_sids(p->mem_ctx, r_u, ref, &names, mapped_count);
00944         if (!NT_STATUS_IS_OK(status)) {
00945                 return status;
00946         }
00947         return r_u->status;
00948 }
00949 
00950 /***************************************************************************
00951  _lsa_lookup_sids2
00952  ***************************************************************************/
00953 
00954 NTSTATUS _lsa_lookup_sids2(pipes_struct *p,
00955                           LSA_Q_LOOKUP_SIDS2 *q_u,
00956                           LSA_R_LOOKUP_SIDS2 *r_u)
00957 {
00958         struct lsa_info *handle;
00959         int num_sids = q_u->sids.num_entries;
00960         uint32 mapped_count = 0;
00961         DOM_R_REF *ref = NULL;
00962 
00963         if ((q_u->level < 1) || (q_u->level > 6)) {
00964                 return NT_STATUS_INVALID_PARAMETER;
00965         }
00966 
00967         if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&handle)) {
00968                 return NT_STATUS_INVALID_HANDLE;
00969         }
00970 
00971         /* check if the user have enough rights */
00972         if (!(handle->access & POLICY_LOOKUP_NAMES)) {
00973                 return NT_STATUS_ACCESS_DENIED;
00974         }
00975 
00976         if (num_sids >  MAX_LOOKUP_SIDS) {
00977                 DEBUG(5,("_lsa_lookup_sids2: limit of %d exceeded, requested %d\n",
00978                          MAX_LOOKUP_SIDS, num_sids));
00979                 return NT_STATUS_NONE_MAPPED;
00980         }
00981 
00982         r_u->status = _lsa_lookup_sids_internal(p,
00983                                                 q_u->level,
00984                                                 num_sids, 
00985                                                 q_u->sids.sid,
00986                                                 &ref,
00987                                                 &r_u->names,
00988                                                 &mapped_count);
00989 
00990         init_reply_lookup_sids2(r_u, ref, mapped_count);
00991         return r_u->status;
00992 }
00993 
00994 /***************************************************************************
00995  _lsa_lookup_sida3
00996  ***************************************************************************/
00997 
00998 NTSTATUS _lsa_lookup_sids3(pipes_struct *p,
00999                           LSA_Q_LOOKUP_SIDS3 *q_u,
01000                           LSA_R_LOOKUP_SIDS3 *r_u)
01001 {
01002         int num_sids = q_u->sids.num_entries;
01003         uint32 mapped_count = 0;
01004         DOM_R_REF *ref = NULL;
01005 
01006         if ((q_u->level < 1) || (q_u->level > 6)) {
01007                 return NT_STATUS_INVALID_PARAMETER;
01008         }
01009 
01010         /* No policy handle on this call. Restrict to crypto connections. */
01011         if (p->auth.auth_type != PIPE_AUTH_TYPE_SCHANNEL) {
01012                 DEBUG(0,("_lsa_lookup_sids3: client %s not using schannel for netlogon\n",
01013                         get_remote_machine_name() ));
01014                 return NT_STATUS_INVALID_PARAMETER;
01015         }
01016 
01017         if (num_sids >  MAX_LOOKUP_SIDS) {
01018                 DEBUG(5,("_lsa_lookup_sids3: limit of %d exceeded, requested %d\n",
01019                          MAX_LOOKUP_SIDS, num_sids));
01020                 return NT_STATUS_NONE_MAPPED;
01021         }
01022 
01023         r_u->status = _lsa_lookup_sids_internal(p,
01024                                                 q_u->level,
01025                                                 num_sids, 
01026                                                 q_u->sids.sid,
01027                                                 &ref,
01028                                                 &r_u->names,
01029                                                 &mapped_count);
01030 
01031         init_reply_lookup_sids3(r_u, ref, mapped_count);
01032         return r_u->status;
01033 }
01034 
01035 static int lsa_lookup_level_to_flags(uint16 level)
01036 {
01037         int flags;
01038 
01039         switch (level) {
01040                 case 1:
01041                         flags = LOOKUP_NAME_ALL;
01042                         break;
01043                 case 2:
01044                         flags = LOOKUP_NAME_DOMAIN|LOOKUP_NAME_REMOTE|LOOKUP_NAME_ISOLATED;
01045                         break;
01046                 case 3:
01047                         flags = LOOKUP_NAME_DOMAIN|LOOKUP_NAME_ISOLATED;
01048                         break;
01049                 case 4:
01050                 case 5:
01051                 case 6:
01052                 default:
01053                         flags = LOOKUP_NAME_NONE;
01054                         break;
01055         }
01056 
01057         return flags;
01058 }
01059 
01060 /***************************************************************************
01061 lsa_reply_lookup_names
01062  ***************************************************************************/
01063 
01064 NTSTATUS _lsa_lookup_names(pipes_struct *p,LSA_Q_LOOKUP_NAMES *q_u, LSA_R_LOOKUP_NAMES *r_u)
01065 {
01066         struct lsa_info *handle;
01067         UNISTR2 *names = q_u->uni_name;
01068         uint32 num_entries = q_u->num_entries;
01069         DOM_R_REF *ref;
01070         DOM_RID *rids;
01071         uint32 mapped_count = 0;
01072         int flags = 0;
01073 
01074         if (num_entries >  MAX_LOOKUP_SIDS) {
01075                 num_entries = MAX_LOOKUP_SIDS;
01076                 DEBUG(5,("_lsa_lookup_names: truncating name lookup list to %d\n", num_entries));
01077         }
01078                 
01079         flags = lsa_lookup_level_to_flags(q_u->lookup_level);
01080 
01081         ref = TALLOC_ZERO_P(p->mem_ctx, DOM_R_REF);
01082         if (!ref) {
01083                 return NT_STATUS_NO_MEMORY;
01084         }
01085 
01086         if (num_entries) {
01087                 rids = TALLOC_ZERO_ARRAY(p->mem_ctx, DOM_RID, num_entries);
01088                 if (!rids) {
01089                         return NT_STATUS_NO_MEMORY;
01090                 }
01091         } else {
01092                 rids = NULL;
01093         }
01094 
01095         if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&handle)) {
01096                 r_u->status = NT_STATUS_INVALID_HANDLE;
01097                 goto done;
01098         }
01099 
01100         /* check if the user have enough rights */
01101         if (!(handle->access & POLICY_LOOKUP_NAMES)) {
01102                 r_u->status = NT_STATUS_ACCESS_DENIED;
01103                 goto done;
01104         }
01105 
01106         /* set up the LSA Lookup RIDs response */
01107         become_root(); /* lookup_name can require root privs */
01108         r_u->status = lookup_lsa_rids(p->mem_ctx, ref, rids, num_entries,
01109                                       names, flags, &mapped_count);
01110         unbecome_root();
01111 
01112 done:
01113 
01114         if (NT_STATUS_IS_OK(r_u->status) && (num_entries != 0) ) {
01115                 if (mapped_count == 0)
01116                         r_u->status = NT_STATUS_NONE_MAPPED;
01117                 else if (mapped_count != num_entries)
01118                         r_u->status = STATUS_SOME_UNMAPPED;
01119         }
01120 
01121         init_reply_lookup_names(r_u, ref, num_entries, rids, mapped_count);
01122         return r_u->status;
01123 }
01124 
01125 /***************************************************************************
01126 lsa_reply_lookup_names2
01127  ***************************************************************************/
01128 
01129 NTSTATUS _lsa_lookup_names2(pipes_struct *p, LSA_Q_LOOKUP_NAMES2 *q_u, LSA_R_LOOKUP_NAMES2 *r_u)
01130 {
01131         struct lsa_info *handle;
01132         UNISTR2 *names = q_u->uni_name;
01133         uint32 num_entries = q_u->num_entries;
01134         DOM_R_REF *ref;
01135         DOM_RID *rids;
01136         DOM_RID2 *rids2;
01137         int i;
01138         uint32 mapped_count = 0;
01139         int flags = 0;
01140 
01141         if (num_entries >  MAX_LOOKUP_SIDS) {
01142                 num_entries = MAX_LOOKUP_SIDS;
01143                 DEBUG(5,("_lsa_lookup_names2: truncating name lookup list to %d\n", num_entries));
01144         }
01145 
01146         flags = lsa_lookup_level_to_flags(q_u->lookup_level);
01147 
01148         ref = TALLOC_ZERO_P(p->mem_ctx, DOM_R_REF);
01149         if (ref == NULL) {
01150                 r_u->status = NT_STATUS_NO_MEMORY;
01151                 return NT_STATUS_NO_MEMORY;
01152         }
01153 
01154         if (num_entries) {
01155                 rids = TALLOC_ZERO_ARRAY(p->mem_ctx, DOM_RID, num_entries);
01156                 rids2 = TALLOC_ZERO_ARRAY(p->mem_ctx, DOM_RID2, num_entries);
01157                 if ((rids == NULL) || (rids2 == NULL)) {
01158                         r_u->status = NT_STATUS_NO_MEMORY;
01159                         return NT_STATUS_NO_MEMORY;
01160                 }
01161         } else {
01162                 rids = NULL;
01163                 rids2 = NULL;
01164         }
01165 
01166         if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&handle)) {
01167                 r_u->status = NT_STATUS_INVALID_HANDLE;
01168                 goto done;
01169         }
01170 
01171         /* check if the user have enough rights */
01172         if (!(handle->access & POLICY_LOOKUP_NAMES)) {
01173                 r_u->status = NT_STATUS_ACCESS_DENIED;
01174                 goto done;
01175         }
01176 
01177         /* set up the LSA Lookup RIDs response */
01178         become_root(); /* lookup_name can require root privs */
01179         r_u->status = lookup_lsa_rids(p->mem_ctx, ref, rids, num_entries,
01180                                       names, flags, &mapped_count);
01181         unbecome_root();
01182 
01183 done:
01184 
01185         if (NT_STATUS_IS_OK(r_u->status)) {
01186                 if (mapped_count == 0) {
01187                         r_u->status = NT_STATUS_NONE_MAPPED;
01188                 } else if (mapped_count != num_entries) {
01189                         r_u->status = STATUS_SOME_UNMAPPED;
01190                 }
01191         }
01192 
01193         /* Convert the rids array to rids2. */
01194         for (i = 0; i < num_entries; i++) {
01195                 rids2[i].type = rids[i].type;
01196                 rids2[i].rid = rids[i].rid;
01197                 rids2[i].rid_idx = rids[i].rid_idx;
01198                 rids2[i].unknown = 0;
01199         }
01200 
01201         init_reply_lookup_names2(r_u, ref, num_entries, rids2, mapped_count);
01202         return r_u->status;
01203 }
01204 
01205 /***************************************************************************
01206 lsa_reply_lookup_names3.
01207  ***************************************************************************/
01208 
01209 NTSTATUS _lsa_lookup_names3(pipes_struct *p, LSA_Q_LOOKUP_NAMES3 *q_u, LSA_R_LOOKUP_NAMES3 *r_u)
01210 {
01211         struct lsa_info *handle;
01212         UNISTR2 *names = q_u->uni_name;
01213         uint32 num_entries = q_u->num_entries;
01214         DOM_R_REF *ref = NULL;
01215         LSA_TRANSLATED_SID3 *trans_sids = NULL;
01216         uint32 mapped_count = 0;
01217         int flags = 0;
01218 
01219         if (num_entries >  MAX_LOOKUP_SIDS) {
01220                 num_entries = MAX_LOOKUP_SIDS;
01221                 DEBUG(5,("_lsa_lookup_names3: truncating name lookup list to %d\n", num_entries));
01222         }
01223                 
01224         /* Probably the lookup_level is some sort of bitmask. */
01225         if (q_u->lookup_level == 1) {
01226                 flags = LOOKUP_NAME_ALL;
01227         }
01228 
01229         ref = TALLOC_ZERO_P(p->mem_ctx, DOM_R_REF);
01230         if (ref == NULL) {
01231                 return NT_STATUS_NO_MEMORY;
01232         }
01233         if (num_entries) {
01234                 trans_sids = TALLOC_ZERO_ARRAY(p->mem_ctx, LSA_TRANSLATED_SID3, num_entries);
01235                 if (!trans_sids) {
01236                         return NT_STATUS_NO_MEMORY;
01237                 }
01238         } else {
01239                 trans_sids = NULL;
01240         }
01241 
01242         if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&handle)) {
01243                 r_u->status = NT_STATUS_INVALID_HANDLE;
01244                 goto done;
01245         }
01246 
01247         /* check if the user have enough rights */
01248         if (!(handle->access & POLICY_LOOKUP_NAMES)) {
01249                 r_u->status = NT_STATUS_ACCESS_DENIED;
01250                 goto done;
01251         }
01252 
01253         /* set up the LSA Lookup SIDs response */
01254         become_root(); /* lookup_name can require root privs */
01255         r_u->status = lookup_lsa_sids(p->mem_ctx, ref, trans_sids, num_entries,
01256                                       names, flags, &mapped_count);
01257         unbecome_root();
01258 
01259 done:
01260 
01261         if (NT_STATUS_IS_OK(r_u->status)) {
01262                 if (mapped_count == 0) {
01263                         r_u->status = NT_STATUS_NONE_MAPPED;
01264                 } else if (mapped_count != num_entries) {
01265                         r_u->status = STATUS_SOME_UNMAPPED;
01266                 }
01267         }
01268 
01269         init_reply_lookup_names3(r_u, ref, num_entries, trans_sids, mapped_count);
01270         return r_u->status;
01271 }
01272 
01273 /***************************************************************************
01274 lsa_reply_lookup_names4.
01275  ***************************************************************************/
01276 
01277 NTSTATUS _lsa_lookup_names4(pipes_struct *p, LSA_Q_LOOKUP_NAMES4 *q_u, LSA_R_LOOKUP_NAMES4 *r_u)
01278 {
01279         UNISTR2 *names = q_u->uni_name;
01280         uint32 num_entries = q_u->num_entries;
01281         DOM_R_REF *ref = NULL;
01282         LSA_TRANSLATED_SID3 *trans_sids = NULL;
01283         uint32 mapped_count = 0;
01284         int flags = 0;
01285 
01286         if (num_entries >  MAX_LOOKUP_SIDS) {
01287                 num_entries = MAX_LOOKUP_SIDS;
01288                 DEBUG(5,("_lsa_lookup_names4: truncating name lookup list to %d\n", num_entries));
01289         }
01290                 
01291         /* Probably the lookup_level is some sort of bitmask. */
01292         if (q_u->lookup_level == 1) {
01293                 flags = LOOKUP_NAME_ALL;
01294         }
01295 
01296         /* No policy handle on this call. Restrict to crypto connections. */
01297         if (p->auth.auth_type != PIPE_AUTH_TYPE_SCHANNEL) {
01298                 DEBUG(0,("_lsa_lookup_names4: client %s not using schannel for netlogon\n",
01299                         get_remote_machine_name() ));
01300                 return NT_STATUS_INVALID_PARAMETER;
01301         }
01302 
01303         ref = TALLOC_ZERO_P(p->mem_ctx, DOM_R_REF);
01304         if (!ref) {
01305                 return NT_STATUS_NO_MEMORY;
01306         }
01307 
01308         if (num_entries) {
01309                 trans_sids = TALLOC_ZERO_ARRAY(p->mem_ctx, LSA_TRANSLATED_SID3, num_entries);
01310                 if (!trans_sids) {
01311                         return NT_STATUS_NO_MEMORY;
01312                 }
01313         } else {
01314                 trans_sids = NULL;
01315         }
01316 
01317         /* set up the LSA Lookup SIDs response */
01318         become_root(); /* lookup_name can require root privs */
01319         r_u->status = lookup_lsa_sids(p->mem_ctx, ref, trans_sids, num_entries,
01320                                       names, flags, &mapped_count);
01321         unbecome_root();
01322 
01323         if (NT_STATUS_IS_OK(r_u->status)) {
01324                 if (mapped_count == 0) {
01325                         r_u->status = NT_STATUS_NONE_MAPPED;
01326                 } else if (mapped_count != num_entries) {
01327                         r_u->status = STATUS_SOME_UNMAPPED;
01328                 }
01329         }
01330 
01331         init_reply_lookup_names4(r_u, ref, num_entries, trans_sids, mapped_count);
01332         return r_u->status;
01333 }
01334 
01335 /***************************************************************************
01336  _lsa_close. Also weird - needs to check if lsa handle is correct. JRA.
01337  ***************************************************************************/
01338 
01339 NTSTATUS _lsa_close(pipes_struct *p, LSA_Q_CLOSE *q_u, LSA_R_CLOSE *r_u)
01340 {
01341         if (!find_policy_by_hnd(p, &q_u->pol, NULL)) {
01342                 return NT_STATUS_INVALID_HANDLE;
01343         }
01344 
01345         close_policy_hnd(p, &q_u->pol);
01346         return NT_STATUS_OK;
01347 }
01348 
01349 /***************************************************************************
01350  ***************************************************************************/
01351 
01352 NTSTATUS _lsa_open_secret(pipes_struct *p, LSA_Q_OPEN_SECRET *q_u, LSA_R_OPEN_SECRET *r_u)
01353 {
01354         return NT_STATUS_OBJECT_NAME_NOT_FOUND;
01355 }
01356 
01357 /***************************************************************************
01358  ***************************************************************************/
01359 
01360 NTSTATUS _lsa_open_trusted_domain(pipes_struct *p, LSA_Q_OPEN_TRUSTED_DOMAIN *q_u, LSA_R_OPEN_TRUSTED_DOMAIN *r_u)
01361 {
01362         return NT_STATUS_OBJECT_NAME_NOT_FOUND;
01363 }
01364 
01365 /***************************************************************************
01366  ***************************************************************************/
01367 
01368 NTSTATUS _lsa_create_trusted_domain(pipes_struct *p, LSA_Q_CREATE_TRUSTED_DOMAIN *q_u, LSA_R_CREATE_TRUSTED_DOMAIN *r_u)
01369 {
01370         return NT_STATUS_ACCESS_DENIED;
01371 }
01372 
01373 /***************************************************************************
01374  ***************************************************************************/
01375 
01376 NTSTATUS _lsa_create_secret(pipes_struct *p, LSA_Q_CREATE_SECRET *q_u, LSA_R_CREATE_SECRET *r_u)
01377 {
01378         return NT_STATUS_ACCESS_DENIED;
01379 }
01380 
01381 /***************************************************************************
01382  ***************************************************************************/
01383 
01384 NTSTATUS _lsa_set_secret(pipes_struct *p, LSA_Q_SET_SECRET *q_u, LSA_R_SET_SECRET *r_u)
01385 {
01386         return NT_STATUS_ACCESS_DENIED;
01387 }
01388 
01389 /***************************************************************************
01390  ***************************************************************************/
01391 
01392 NTSTATUS _lsa_delete_object(pipes_struct *p, LSA_Q_DELETE_OBJECT *q_u, LSA_R_DELETE_OBJECT *r_u)
01393 {
01394         return NT_STATUS_ACCESS_DENIED;
01395 }
01396 
01397 /***************************************************************************
01398 _lsa_enum_privs.
01399  ***************************************************************************/
01400 
01401 NTSTATUS _lsa_enum_privs(pipes_struct *p, LSA_Q_ENUM_PRIVS *q_u, LSA_R_ENUM_PRIVS *r_u)
01402 {
01403         struct lsa_info *handle;
01404         uint32 i;
01405         uint32 enum_context = q_u->enum_context;
01406         int num_privs = count_all_privileges();
01407         LSA_PRIV_ENTRY *entries = NULL;
01408         LUID_ATTR luid;
01409 
01410         /* remember that the enum_context starts at 0 and not 1 */
01411 
01412         if ( enum_context >= num_privs )
01413                 return NT_STATUS_NO_MORE_ENTRIES;
01414                 
01415         DEBUG(10,("_lsa_enum_privs: enum_context:%d total entries:%d\n", 
01416                 enum_context, num_privs));
01417         
01418         if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&handle))
01419                 return NT_STATUS_INVALID_HANDLE;
01420 
01421         /* check if the user have enough rights
01422            I don't know if it's the right one. not documented.  */
01423 
01424         if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION))
01425                 return NT_STATUS_ACCESS_DENIED;
01426 
01427         if (num_privs) {
01428                 if ( !(entries = TALLOC_ZERO_ARRAY(p->mem_ctx, LSA_PRIV_ENTRY, num_privs )) )
01429                         return NT_STATUS_NO_MEMORY;
01430         } else {
01431                 entries = NULL;
01432         }
01433 
01434         for (i = 0; i < num_privs; i++) {
01435                 if( i < enum_context) {
01436                         init_unistr2(&entries[i].name, NULL, UNI_FLAGS_NONE);
01437                         init_uni_hdr(&entries[i].hdr_name, &entries[i].name);
01438                         
01439                         entries[i].luid_low = 0;
01440                         entries[i].luid_high = 0;
01441                 } else {
01442                         init_unistr2(&entries[i].name, privs[i].name, UNI_FLAGS_NONE);
01443                         init_uni_hdr(&entries[i].hdr_name, &entries[i].name);
01444                         
01445                         luid = get_privilege_luid( &privs[i].se_priv );
01446                         
01447                         entries[i].luid_low = luid.luid.low;
01448                         entries[i].luid_high = luid.luid.high;
01449                 }
01450         }
01451 
01452         enum_context = num_privs;
01453         
01454         init_lsa_r_enum_privs(r_u, enum_context, num_privs, entries);
01455 
01456         return NT_STATUS_OK;
01457 }
01458 
01459 /***************************************************************************
01460 _lsa_priv_get_dispname.
01461  ***************************************************************************/
01462 
01463 NTSTATUS _lsa_priv_get_dispname(pipes_struct *p, LSA_Q_PRIV_GET_DISPNAME *q_u, LSA_R_PRIV_GET_DISPNAME *r_u)
01464 {
01465         struct lsa_info *handle;
01466         fstring name_asc;
01467         const char *description;
01468 
01469         if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&handle))
01470                 return NT_STATUS_INVALID_HANDLE;
01471 
01472         /* check if the user have enough rights */
01473 
01474         /*
01475          * I don't know if it's the right one. not documented.
01476          */
01477         if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION))
01478                 return NT_STATUS_ACCESS_DENIED;
01479 
01480         unistr2_to_ascii(name_asc, &q_u->name, sizeof(name_asc));
01481 
01482         DEBUG(10,("_lsa_priv_get_dispname: name = %s\n", name_asc));
01483 
01484         description = get_privilege_dispname( name_asc );
01485         
01486         if ( description ) {
01487                 DEBUG(10,("_lsa_priv_get_dispname: display name = %s\n", description));
01488                 
01489                 init_unistr2(&r_u->desc, description, UNI_FLAGS_NONE);
01490                 init_uni_hdr(&r_u->hdr_desc, &r_u->desc);
01491 
01492                 r_u->ptr_info = 0xdeadbeef;
01493                 r_u->lang_id = q_u->lang_id;
01494                 
01495                 return NT_STATUS_OK;
01496         } else {
01497                 DEBUG(10,("_lsa_priv_get_dispname: doesn't exist\n"));
01498                 
01499                 r_u->ptr_info = 0;
01500                 
01501                 return NT_STATUS_NO_SUCH_PRIVILEGE;
01502         }
01503 }
01504 
01505 /***************************************************************************
01506 _lsa_enum_accounts.
01507  ***************************************************************************/
01508 
01509 NTSTATUS _lsa_enum_accounts(pipes_struct *p, LSA_Q_ENUM_ACCOUNTS *q_u, LSA_R_ENUM_ACCOUNTS *r_u)
01510 {
01511         struct lsa_info *handle;
01512         DOM_SID *sid_list;
01513         int i, j, num_entries;
01514         LSA_SID_ENUM *sids=&r_u->sids;
01515         NTSTATUS ret;
01516 
01517         if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&handle))
01518                 return NT_STATUS_INVALID_HANDLE;
01519 
01520         if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION))
01521                 return NT_STATUS_ACCESS_DENIED;
01522 
01523         sid_list = NULL;
01524         num_entries = 0;
01525 
01526         /* The only way we can currently find out all the SIDs that have been
01527            privileged is to scan all privileges */
01528 
01529         if (!NT_STATUS_IS_OK(ret = privilege_enumerate_accounts(&sid_list, &num_entries))) {
01530                 return ret;
01531         }
01532 
01533         if (q_u->enum_context >= num_entries)
01534                 return NT_STATUS_NO_MORE_ENTRIES;
01535 
01536         if (num_entries-q_u->enum_context) {
01537                 sids->ptr_sid = TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_entries-q_u->enum_context);
01538                 sids->sid = TALLOC_ZERO_ARRAY(p->mem_ctx, DOM_SID2, num_entries-q_u->enum_context);
01539 
01540                 if (sids->ptr_sid==NULL || sids->sid==NULL) {
01541                         SAFE_FREE(sid_list);
01542                         return NT_STATUS_NO_MEMORY;
01543                 }
01544         } else {
01545                 sids->ptr_sid = NULL;
01546                 sids->sid = NULL;
01547         }
01548 
01549         for (i = q_u->enum_context, j = 0; i < num_entries; i++, j++) {
01550                 init_dom_sid2(&(*sids).sid[j], &sid_list[i]);
01551                 (*sids).ptr_sid[j] = 1;
01552         }
01553 
01554         talloc_free(sid_list);
01555 
01556         init_lsa_r_enum_accounts(r_u, num_entries);
01557 
01558         return NT_STATUS_OK;
01559 }
01560 
01561 
01562 NTSTATUS _lsa_unk_get_connuser(pipes_struct *p, LSA_Q_UNK_GET_CONNUSER *q_u, LSA_R_UNK_GET_CONNUSER *r_u)
01563 {
01564         fstring username, domname;
01565         user_struct *vuser = get_valid_user_struct(p->vuid);
01566   
01567         if (vuser == NULL)
01568                 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
01569   
01570         fstrcpy(username, vuser->user.smb_name);
01571         fstrcpy(domname, vuser->user.domain);
01572   
01573         r_u->ptr_user_name = 1;
01574         init_unistr2(&r_u->uni2_user_name, username, UNI_STR_TERMINATE);
01575         init_uni_hdr(&r_u->hdr_user_name, &r_u->uni2_user_name);
01576 
01577         r_u->unk1 = 1;
01578   
01579         r_u->ptr_dom_name = 1;
01580         init_unistr2(&r_u->uni2_dom_name, domname,  UNI_STR_TERMINATE);
01581         init_uni_hdr(&r_u->hdr_dom_name, &r_u->uni2_dom_name);
01582 
01583         r_u->status = NT_STATUS_OK;
01584   
01585         return r_u->status;
01586 }
01587 
01588 /***************************************************************************
01589  Lsa Create Account 
01590  ***************************************************************************/
01591 
01592 NTSTATUS _lsa_create_account(pipes_struct *p, LSA_Q_CREATEACCOUNT *q_u, LSA_R_CREATEACCOUNT *r_u)
01593 {
01594         struct lsa_info *handle;
01595         struct lsa_info *info;
01596 
01597         /* find the connection policy handle. */
01598         if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&handle))
01599                 return NT_STATUS_INVALID_HANDLE;
01600 
01601         /* check if the user have enough rights */
01602 
01603         /*
01604          * I don't know if it's the right one. not documented.
01605          * but guessed with rpcclient.
01606          */
01607         if (!(handle->access & POLICY_GET_PRIVATE_INFORMATION))
01608                 return NT_STATUS_ACCESS_DENIED;
01609 
01610         /* check to see if the pipe_user is a Domain Admin since 
01611            account_pol.tdb was already opened as root, this is all we have */
01612            
01613         if ( !nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS ) )
01614                 return NT_STATUS_ACCESS_DENIED;
01615                 
01616         if ( is_privileged_sid( &q_u->sid.sid ) )
01617                 return NT_STATUS_OBJECT_NAME_COLLISION;
01618 
01619         /* associate the user/group SID with the (unique) handle. */
01620         
01621         if ((info = SMB_MALLOC_P(struct lsa_info)) == NULL)
01622                 return NT_STATUS_NO_MEMORY;
01623 
01624         ZERO_STRUCTP(info);
01625         info->sid = q_u->sid.sid;
01626         info->access = q_u->access;
01627 
01628         /* get a (unique) handle.  open a policy on it. */
01629         if (!create_policy_hnd(p, &r_u->pol, free_lsa_info, (void *)info))
01630                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
01631 
01632         return privilege_create_account( &info->sid );
01633 }
01634 
01635 
01636 /***************************************************************************
01637  Lsa Open Account
01638  ***************************************************************************/
01639 
01640 NTSTATUS _lsa_open_account(pipes_struct *p, LSA_Q_OPENACCOUNT *q_u, LSA_R_OPENACCOUNT *r_u)
01641 {
01642         struct lsa_info *handle;
01643         struct lsa_info *info;
01644 
01645         /* find the connection policy handle. */
01646         if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&handle))
01647                 return NT_STATUS_INVALID_HANDLE;
01648 
01649         /* check if the user have enough rights */
01650 
01651         /*
01652          * I don't know if it's the right one. not documented.
01653          * but guessed with rpcclient.
01654          */
01655         if (!(handle->access & POLICY_GET_PRIVATE_INFORMATION))
01656                 return NT_STATUS_ACCESS_DENIED;
01657 
01658         /* TODO: Fis the parsing routine before reenabling this check! */
01659         #if 0
01660         if (!lookup_sid(&handle->sid, dom_name, name, &type))
01661                 return NT_STATUS_ACCESS_DENIED;
01662         #endif
01663         /* associate the user/group SID with the (unique) handle. */
01664         if ((info = SMB_MALLOC_P(struct lsa_info)) == NULL)
01665                 return NT_STATUS_NO_MEMORY;
01666 
01667         ZERO_STRUCTP(info);
01668         info->sid = q_u->sid.sid;
01669         info->access = q_u->access;
01670 
01671         /* get a (unique) handle.  open a policy on it. */
01672         if (!create_policy_hnd(p, &r_u->pol, free_lsa_info, (void *)info))
01673                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
01674 
01675         return NT_STATUS_OK;
01676 }
01677 
01678 /***************************************************************************
01679  For a given SID, enumerate all the privilege this account has.
01680  ***************************************************************************/
01681 
01682 NTSTATUS _lsa_enum_privsaccount(pipes_struct *p, prs_struct *ps, LSA_Q_ENUMPRIVSACCOUNT *q_u, LSA_R_ENUMPRIVSACCOUNT *r_u)
01683 {
01684         struct lsa_info *info=NULL;
01685         SE_PRIV mask;
01686         PRIVILEGE_SET privileges;
01687 
01688         /* find the connection policy handle. */
01689         if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info))
01690                 return NT_STATUS_INVALID_HANDLE;
01691 
01692         if ( !get_privileges_for_sids( &mask, &info->sid, 1 ) ) 
01693                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
01694 
01695         privilege_set_init( &privileges );
01696 
01697         if ( se_priv_to_privilege_set( &privileges, &mask ) ) {
01698 
01699                 DEBUG(10,("_lsa_enum_privsaccount: %s has %d privileges\n", 
01700                         sid_string_static(&info->sid), privileges.count));
01701 
01702                 r_u->status = init_lsa_r_enum_privsaccount(ps->mem_ctx, r_u, privileges.set, privileges.count, 0);
01703         }
01704         else
01705                 r_u->status = NT_STATUS_NO_SUCH_PRIVILEGE;
01706 
01707         privilege_set_free( &privileges );
01708 
01709         return r_u->status;
01710 }
01711 
01712 /***************************************************************************
01713  
01714  ***************************************************************************/
01715 
01716 NTSTATUS _lsa_getsystemaccount(pipes_struct *p, LSA_Q_GETSYSTEMACCOUNT *q_u, LSA_R_GETSYSTEMACCOUNT *r_u)
01717 {
01718         struct lsa_info *info=NULL;
01719 
01720         /* find the connection policy handle. */
01721 
01722         if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info))
01723                 return NT_STATUS_INVALID_HANDLE;
01724 
01725         if (!lookup_sid(p->mem_ctx, &info->sid, NULL, NULL, NULL))
01726                 return NT_STATUS_ACCESS_DENIED;
01727 
01728         /*
01729           0x01 -> Log on locally
01730           0x02 -> Access this computer from network
01731           0x04 -> Log on as a batch job
01732           0x10 -> Log on as a service
01733           
01734           they can be ORed together
01735         */
01736 
01737         r_u->access = PR_LOG_ON_LOCALLY | PR_ACCESS_FROM_NETWORK;
01738 
01739         return NT_STATUS_OK;
01740 }
01741 
01742 /***************************************************************************
01743   update the systemaccount information
01744  ***************************************************************************/
01745 
01746 NTSTATUS _lsa_setsystemaccount(pipes_struct *p, LSA_Q_SETSYSTEMACCOUNT *q_u, LSA_R_SETSYSTEMACCOUNT *r_u)
01747 {
01748         struct lsa_info *info=NULL;
01749         GROUP_MAP map;
01750         r_u->status = NT_STATUS_OK;
01751 
01752         /* find the connection policy handle. */
01753         if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info))
01754                 return NT_STATUS_INVALID_HANDLE;
01755 
01756         /* check to see if the pipe_user is a Domain Admin since 
01757            account_pol.tdb was already opened as root, this is all we have */
01758            
01759         if ( !nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS ) )
01760                 return NT_STATUS_ACCESS_DENIED;
01761 
01762         if (!pdb_getgrsid(&map, info->sid))
01763                 return NT_STATUS_NO_SUCH_GROUP;
01764 
01765         return pdb_update_group_mapping_entry(&map);
01766 }
01767 
01768 /***************************************************************************
01769  For a given SID, add some privileges.
01770  ***************************************************************************/
01771 
01772 NTSTATUS _lsa_addprivs(pipes_struct *p, LSA_Q_ADDPRIVS *q_u, LSA_R_ADDPRIVS *r_u)
01773 {
01774         struct lsa_info *info = NULL;
01775         SE_PRIV mask;
01776         PRIVILEGE_SET *set = NULL;
01777         struct current_user user;
01778 
01779         /* find the connection policy handle. */
01780         if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info))
01781                 return NT_STATUS_INVALID_HANDLE;
01782                 
01783         /* check to see if the pipe_user is root or a Domain Admin since 
01784            account_pol.tdb was already opened as root, this is all we have */
01785            
01786         get_current_user( &user, p );
01787         if ( user.ut.uid != sec_initial_uid() 
01788                 && !nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS ) )
01789         {
01790                 return NT_STATUS_ACCESS_DENIED;
01791         }
01792 
01793         set = &q_u->set;
01794 
01795         if ( !privilege_set_to_se_priv( &mask, set ) )
01796                 return NT_STATUS_NO_SUCH_PRIVILEGE;
01797 
01798         if ( !grant_privilege( &info->sid, &mask ) ) {
01799                 DEBUG(3,("_lsa_addprivs: grant_privilege(%s) failed!\n",
01800                         sid_string_static(&info->sid) ));
01801                 DEBUG(3,("Privilege mask:\n"));
01802                 dump_se_priv( DBGC_ALL, 3, &mask );
01803                 return NT_STATUS_NO_SUCH_PRIVILEGE;
01804         }
01805 
01806         return NT_STATUS_OK;
01807 }
01808 
01809 /***************************************************************************
01810  For a given SID, remove some privileges.
01811  ***************************************************************************/
01812 
01813 NTSTATUS _lsa_removeprivs(pipes_struct *p, LSA_Q_REMOVEPRIVS *q_u, LSA_R_REMOVEPRIVS *r_u)
01814 {
01815         struct lsa_info *info = NULL;
01816         SE_PRIV mask;
01817         PRIVILEGE_SET *set = NULL;
01818         struct current_user user;
01819 
01820         /* find the connection policy handle. */
01821         if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info))
01822                 return NT_STATUS_INVALID_HANDLE;
01823 
01824         /* check to see if the pipe_user is root or a Domain Admin since 
01825            account_pol.tdb was already opened as root, this is all we have */
01826            
01827         get_current_user( &user, p );
01828         if ( user.ut.uid != sec_initial_uid()
01829                 && !nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS ) ) 
01830         {
01831                 return NT_STATUS_ACCESS_DENIED;
01832         }
01833 
01834         set = &q_u->set;
01835 
01836         if ( !privilege_set_to_se_priv( &mask, set ) )
01837                 return NT_STATUS_NO_SUCH_PRIVILEGE;
01838 
01839         if ( !revoke_privilege( &info->sid, &mask ) ) {
01840                 DEBUG(3,("_lsa_removeprivs: revoke_privilege(%s) failed!\n",
01841                         sid_string_static(&info->sid) ));
01842                 DEBUG(3,("Privilege mask:\n"));
01843                 dump_se_priv( DBGC_ALL, 3, &mask );
01844                 return NT_STATUS_NO_SUCH_PRIVILEGE;
01845         }
01846 
01847         return NT_STATUS_OK;
01848 }
01849 
01850 /***************************************************************************
01851  For a given SID, remove some privileges.
01852  ***************************************************************************/
01853 
01854 NTSTATUS _lsa_query_secobj(pipes_struct *p, LSA_Q_QUERY_SEC_OBJ *q_u, LSA_R_QUERY_SEC_OBJ *r_u)
01855 {
01856         struct lsa_info *handle=NULL;
01857         SEC_DESC *psd = NULL;
01858         size_t sd_size;
01859         NTSTATUS status;
01860 
01861         r_u->status = NT_STATUS_OK;
01862 
01863         /* find the connection policy handle. */
01864         if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&handle))
01865                 return NT_STATUS_INVALID_HANDLE;
01866 
01867         /* check if the user have enough rights */
01868         if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION))
01869                 return NT_STATUS_ACCESS_DENIED;
01870 
01871 
01872         switch (q_u->sec_info) {
01873         case 1:
01874                 /* SD contains only the owner */
01875 
01876                 status=lsa_get_generic_sd(p->mem_ctx, &psd, &sd_size);
01877                 if(!NT_STATUS_IS_OK(status))
01878                         return NT_STATUS_NO_MEMORY;
01879 
01880 
01881                 if((r_u->buf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
01882                         return NT_STATUS_NO_MEMORY;
01883                 break;
01884         case 4:
01885                 /* SD contains only the ACL */
01886 
01887                 status=lsa_get_generic_sd(p->mem_ctx, &psd, &sd_size);
01888                 if(!NT_STATUS_IS_OK(status))
01889                         return NT_STATUS_NO_MEMORY;
01890 
01891                 if((r_u->buf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
01892                         return NT_STATUS_NO_MEMORY;
01893                 break;
01894         default:
01895                 return NT_STATUS_INVALID_LEVEL;
01896         }
01897 
01898         r_u->ptr=1;
01899 
01900         return r_u->status;
01901 }
01902 
01903 #if 0   /* AD DC work in ongoing in Samba 4 */
01904 
01905 /***************************************************************************
01906  ***************************************************************************/
01907 
01908 NTSTATUS _lsa_query_info2(pipes_struct *p, LSA_Q_QUERY_INFO2 *q_u, LSA_R_QUERY_INFO2 *r_u)
01909 {
01910         struct lsa_info *handle;
01911         const char *nb_name;
01912         char *dns_name = NULL;
01913         char *forest_name = NULL;
01914         DOM_SID *sid = NULL;
01915         struct GUID guid;
01916         fstring dnsdomname;
01917 
01918         ZERO_STRUCT(guid);
01919         r_u->status = NT_STATUS_OK;
01920 
01921         if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&handle))
01922                 return NT_STATUS_INVALID_HANDLE;
01923 
01924         switch (q_u->info_class) {
01925         case 0x0c:
01926                 /* check if the user have enough rights */
01927                 if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION))
01928                         return NT_STATUS_ACCESS_DENIED;
01929 
01930                 /* Request PolicyPrimaryDomainInformation. */
01931                 switch (lp_server_role()) {
01932                         case ROLE_DOMAIN_PDC:
01933                         case ROLE_DOMAIN_BDC:
01934                                 nb_name = get_global_sam_name();
01935                                 /* ugly temp hack for these next two */
01936 
01937                                 /* This should be a 'netbios domain -> DNS domain' mapping */
01938                                 dnsdomname[0] = '\0';
01939                                 get_mydnsdomname(dnsdomname);
01940                                 strlower_m(dnsdomname);
01941                                 
01942                                 dns_name = dnsdomname;
01943                                 forest_name = dnsdomname;
01944 
01945                                 sid = get_global_sam_sid();
01946                                 secrets_fetch_domain_guid(lp_workgroup(), &guid);
01947                                 break;
01948                         default:
01949                                 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
01950                 }
01951                 init_dns_dom_info(&r_u->info.dns_dom_info, nb_name, dns_name, 
01952                                   forest_name,&guid,sid);
01953                 break;
01954         default:
01955                 DEBUG(0,("_lsa_query_info2: unknown info level in Lsa Query: %d\n", q_u->info_class));
01956                 r_u->status = NT_STATUS_INVALID_INFO_CLASS;
01957                 break;
01958         }
01959 
01960         if (NT_STATUS_IS_OK(r_u->status)) {
01961                 r_u->ptr = 0x1;
01962                 r_u->info_class = q_u->info_class;
01963         }
01964 
01965         return r_u->status;
01966 }
01967 #endif  /* AD DC work in ongoing in Samba 4 */
01968 
01969 /***************************************************************************
01970  ***************************************************************************/
01971 
01972 NTSTATUS _lsa_add_acct_rights(pipes_struct *p, LSA_Q_ADD_ACCT_RIGHTS *q_u, LSA_R_ADD_ACCT_RIGHTS *r_u)
01973 {
01974         struct lsa_info *info = NULL;
01975         int i = 0;
01976         DOM_SID sid;
01977         fstring privname;
01978         UNISTR4_ARRAY *uni_privnames = q_u->rights;
01979         struct current_user user;
01980         
01981 
01982         /* find the connection policy handle. */
01983         if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info))
01984                 return NT_STATUS_INVALID_HANDLE;
01985                 
01986         /* check to see if the pipe_user is a Domain Admin since 
01987            account_pol.tdb was already opened as root, this is all we have */
01988            
01989         get_current_user( &user, p );
01990         if ( user.ut.uid != sec_initial_uid()
01991                 && !nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS ) ) 
01992         {
01993                 return NT_STATUS_ACCESS_DENIED;
01994         }
01995 
01996         /* according to an NT4 PDC, you can add privileges to SIDs even without
01997            call_lsa_create_account() first.  And you can use any arbitrary SID. */
01998            
01999         sid_copy( &sid, &q_u->sid.sid );
02000         
02001         /* just a little sanity check */
02002         
02003         if ( q_u->count != uni_privnames->count ) {
02004                 DEBUG(0,("_lsa_add_acct_rights: count != number of UNISTR2 elements!\n"));
02005                 return NT_STATUS_INVALID_HANDLE;        
02006         }
02007                 
02008         for ( i=0; i<q_u->count; i++ ) {
02009                 UNISTR4 *uni4_str = &uni_privnames->strings[i];
02010 
02011                 /* only try to add non-null strings */
02012 
02013                 if ( !uni4_str->string )
02014                         continue;
02015 
02016                 rpcstr_pull( privname, uni4_str->string->buffer, sizeof(privname), -1, STR_TERMINATE );
02017                 
02018                 if ( !grant_privilege_by_name( &sid, privname ) ) {
02019                         DEBUG(2,("_lsa_add_acct_rights: Failed to add privilege [%s]\n", privname ));
02020                         return NT_STATUS_NO_SUCH_PRIVILEGE;
02021                 }
02022         }
02023 
02024         return NT_STATUS_OK;
02025 }
02026 
02027 /***************************************************************************
02028  ***************************************************************************/
02029 
02030 NTSTATUS _lsa_remove_acct_rights(pipes_struct *p, LSA_Q_REMOVE_ACCT_RIGHTS *q_u, LSA_R_REMOVE_ACCT_RIGHTS *r_u)
02031 {
02032         struct lsa_info *info = NULL;
02033         int i = 0;
02034         DOM_SID sid;
02035         fstring privname;
02036         UNISTR4_ARRAY *uni_privnames = q_u->rights;
02037         struct current_user user;
02038         
02039 
02040         /* find the connection policy handle. */
02041         if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info))
02042                 return NT_STATUS_INVALID_HANDLE;
02043                 
02044         /* check to see if the pipe_user is a Domain Admin since 
02045            account_pol.tdb was already opened as root, this is all we have */
02046            
02047         get_current_user( &user, p );
02048         if ( user.ut.uid != sec_initial_uid()
02049                 && !nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS ) )
02050         {
02051                 return NT_STATUS_ACCESS_DENIED;
02052         }
02053 
02054         sid_copy( &sid, &q_u->sid.sid );
02055 
02056         if ( q_u->removeall ) {
02057                 if ( !revoke_all_privileges( &sid ) ) 
02058                         return NT_STATUS_ACCESS_DENIED;
02059         
02060                 return NT_STATUS_OK;
02061         }
02062         
02063         /* just a little sanity check */
02064         
02065         if ( q_u->count != uni_privnames->count ) {
02066                 DEBUG(0,("_lsa_add_acct_rights: count != number of UNISTR2 elements!\n"));
02067                 return NT_STATUS_INVALID_HANDLE;        
02068         }
02069                 
02070         for ( i=0; i<q_u->count; i++ ) {
02071                 UNISTR4 *uni4_str = &uni_privnames->strings[i];
02072 
02073                 /* only try to add non-null strings */
02074 
02075                 if ( !uni4_str->string )
02076                         continue;
02077 
02078                 rpcstr_pull( privname, uni4_str->string->buffer, sizeof(privname), -1, STR_TERMINATE );
02079                 
02080                 if ( !revoke_privilege_by_name( &sid, privname ) ) {
02081                         DEBUG(2,("_lsa_remove_acct_rights: Failed to revoke privilege [%s]\n", privname ));
02082                         return NT_STATUS_NO_SUCH_PRIVILEGE;
02083                 }
02084         }
02085 
02086         return NT_STATUS_OK;
02087 }
02088 
02089 
02090 /***************************************************************************
02091  ***************************************************************************/
02092 
02093 NTSTATUS _lsa_enum_acct_rights(pipes_struct *p, LSA_Q_ENUM_ACCT_RIGHTS *q_u, LSA_R_ENUM_ACCT_RIGHTS *r_u)
02094 {
02095         struct lsa_info *info = NULL;
02096         DOM_SID sid;
02097         PRIVILEGE_SET privileges;
02098         SE_PRIV mask;
02099         
02100 
02101         /* find the connection policy handle. */
02102         
02103         if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info))
02104                 return NT_STATUS_INVALID_HANDLE;
02105                 
02106         /* according to an NT4 PDC, you can add privileges to SIDs even without
02107            call_lsa_create_account() first.  And you can use any arbitrary SID. */
02108            
02109         sid_copy( &sid, &q_u->sid.sid );
02110         
02111         if ( !get_privileges_for_sids( &mask, &sid, 1 ) )
02112                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
02113 
02114         privilege_set_init( &privileges );
02115 
02116         if ( se_priv_to_privilege_set( &privileges, &mask ) ) {
02117 
02118                 DEBUG(10,("_lsa_enum_acct_rights: %s has %d privileges\n", 
02119                         sid_string_static(&sid), privileges.count));
02120 
02121                 r_u->status = init_r_enum_acct_rights( r_u, &privileges );
02122         }
02123         else 
02124                 r_u->status = NT_STATUS_NO_SUCH_PRIVILEGE;
02125 
02126         privilege_set_free( &privileges );
02127 
02128         return r_u->status;
02129 }
02130 
02131 
02132 /***************************************************************************
02133  ***************************************************************************/
02134 
02135 NTSTATUS _lsa_lookup_priv_value(pipes_struct *p, LSA_Q_LOOKUP_PRIV_VALUE *q_u, LSA_R_LOOKUP_PRIV_VALUE *r_u)
02136 {
02137         struct lsa_info *info = NULL;
02138         fstring name;
02139         LUID_ATTR priv_luid;
02140         SE_PRIV mask;
02141         
02142         /* find the connection policy handle. */
02143         
02144         if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info))
02145                 return NT_STATUS_INVALID_HANDLE;
02146                 
02147         unistr2_to_ascii(name, &q_u->privname.unistring, sizeof(name));
02148         
02149         DEBUG(10,("_lsa_lookup_priv_value: name = %s\n", name));
02150 
02151         if ( !se_priv_from_name( name, &mask ) )
02152                 return NT_STATUS_NO_SUCH_PRIVILEGE;
02153 
02154         priv_luid = get_privilege_luid( &mask );
02155 
02156         r_u->luid.low  = priv_luid.luid.low;
02157         r_u->luid.high = priv_luid.luid.high;
02158                 
02159 
02160         return NT_STATUS_OK;
02161 }

Sambaに対してSat Aug 29 21:23:19 2009に生成されました。  doxygen 1.4.7