root/source4/libcli/util/clilsa.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. smblsa_connect
  2. smblsa_sid_privileges
  3. smblsa_sid_check_privilege
  4. smblsa_lookup_sid
  5. smblsa_lookup_name
  6. smblsa_sid_add_privileges
  7. smblsa_sid_del_privileges

   1 /* 
   2    Unix SMB/CIFS implementation.
   3 
   4    lsa calls for file sharing connections
   5 
   6    Copyright (C) Andrew Tridgell 2004
   7    
   8    This program is free software; you can redistribute it and/or modify
   9    it under the terms of the GNU General Public License as published by
  10    the Free Software Foundation; either version 3 of the License, or
  11    (at your option) any later version.
  12    
  13    This program is distributed in the hope that it will be useful,
  14    but WITHOUT ANY WARRANTY; without even the implied warranty of
  15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16    GNU General Public License for more details.
  17    
  18    You should have received a copy of the GNU General Public License
  19    along with this program.  If not, see <http://www.gnu.org/licenses/>.
  20 */
  21 
  22 /*
  23   when dealing with ACLs the file sharing client code needs to
  24   sometimes make LSA RPC calls. This code provides an easy interface
  25   for doing those calls.  
  26 */
  27 
  28 #include "includes.h"
  29 #include "libcli/raw/libcliraw.h"
  30 #include "libcli/libcli.h"
  31 #include "libcli/security/security.h"
  32 #include "librpc/gen_ndr/ndr_lsa.h"
  33 #include "librpc/gen_ndr/ndr_lsa_c.h"
  34 #include "libcli/util/clilsa.h"
  35 
  36 struct smblsa_state {
  37         struct dcerpc_pipe *pipe;
  38         struct smbcli_tree *ipc_tree;
  39         struct policy_handle handle;
  40 };
  41 
  42 /*
  43   establish the lsa pipe connection
  44 */
  45 static NTSTATUS smblsa_connect(struct smbcli_state *cli)
     /* [<][>][^][v][top][bottom][index][help] */
  46 {
  47         struct smblsa_state *lsa;
  48         NTSTATUS status;
  49         struct lsa_OpenPolicy r;
  50         uint16_t system_name = '\\';
  51         union smb_tcon tcon;
  52         struct lsa_ObjectAttribute attr;
  53         struct lsa_QosInfo qos;
  54 
  55         if (cli->lsa != NULL) {
  56                 return NT_STATUS_OK;
  57         }
  58 
  59         lsa = talloc(cli, struct smblsa_state);
  60         if (lsa == NULL) {
  61                 return NT_STATUS_NO_MEMORY;
  62         }
  63 
  64         lsa->ipc_tree = smbcli_tree_init(cli->session, lsa, false);
  65         if (lsa->ipc_tree == NULL) {
  66                 return NT_STATUS_NO_MEMORY;
  67         }
  68 
  69         /* connect to IPC$ */
  70         tcon.generic.level = RAW_TCON_TCONX;
  71         tcon.tconx.in.flags = 0;
  72         tcon.tconx.in.password = data_blob(NULL, 0);
  73         tcon.tconx.in.path = "ipc$";
  74         tcon.tconx.in.device = "IPC";   
  75         status = smb_raw_tcon(lsa->ipc_tree, lsa, &tcon);
  76         if (!NT_STATUS_IS_OK(status)) {
  77                 talloc_free(lsa);
  78                 return status;
  79         }
  80         lsa->ipc_tree->tid = tcon.tconx.out.tid;
  81 
  82         lsa->pipe = dcerpc_pipe_init(lsa, cli->transport->socket->event.ctx,
  83                                                                  cli->transport->iconv_convenience);
  84         if (lsa->pipe == NULL) {
  85                 talloc_free(lsa);
  86                 return NT_STATUS_NO_MEMORY;
  87         }
  88 
  89         /* open the LSA pipe */
  90         status = dcerpc_pipe_open_smb(lsa->pipe, lsa->ipc_tree, NDR_LSARPC_NAME);
  91         if (!NT_STATUS_IS_OK(status)) {
  92                 talloc_free(lsa);
  93                 return status;
  94         }
  95 
  96         /* bind to the LSA pipe */
  97         status = dcerpc_bind_auth_none(lsa->pipe, &ndr_table_lsarpc);
  98         if (!NT_STATUS_IS_OK(status)) {
  99                 talloc_free(lsa);
 100                 return status;
 101         }
 102 
 103 
 104         /* open a lsa policy handle */
 105         qos.len = 0;
 106         qos.impersonation_level = 2;
 107         qos.context_mode = 1;
 108         qos.effective_only = 0;
 109 
 110         attr.len = 0;
 111         attr.root_dir = NULL;
 112         attr.object_name = NULL;
 113         attr.attributes = 0;
 114         attr.sec_desc = NULL;
 115         attr.sec_qos = &qos;
 116 
 117         r.in.system_name = &system_name;
 118         r.in.attr = &attr;
 119         r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
 120         r.out.handle = &lsa->handle;
 121 
 122         status = dcerpc_lsa_OpenPolicy(lsa->pipe, lsa, &r);
 123         if (!NT_STATUS_IS_OK(status)) {
 124                 talloc_free(lsa);
 125                 return status;
 126         }
 127 
 128         cli->lsa = lsa;
 129         
 130         return NT_STATUS_OK;
 131 }
 132 
 133 
 134 /*
 135   return the set of privileges for the given sid
 136 */
 137 NTSTATUS smblsa_sid_privileges(struct smbcli_state *cli, struct dom_sid *sid, 
     /* [<][>][^][v][top][bottom][index][help] */
 138                                TALLOC_CTX *mem_ctx,
 139                                struct lsa_RightSet *rights)
 140 {
 141         NTSTATUS status;
 142         struct lsa_EnumAccountRights r;
 143 
 144         status = smblsa_connect(cli);
 145         if (!NT_STATUS_IS_OK(status)) {
 146                 return status;
 147         }
 148 
 149         r.in.handle = &cli->lsa->handle;
 150         r.in.sid = sid;
 151         r.out.rights = rights;
 152 
 153         return dcerpc_lsa_EnumAccountRights(cli->lsa->pipe, mem_ctx, &r);
 154 }
 155 
 156 
 157 /*
 158   check if a named sid has a particular named privilege
 159 */
 160 NTSTATUS smblsa_sid_check_privilege(struct smbcli_state *cli, 
     /* [<][>][^][v][top][bottom][index][help] */
 161                                     const char *sid_str,
 162                                     const char *privilege)
 163 {
 164         struct lsa_RightSet rights;
 165         NTSTATUS status;
 166         TALLOC_CTX *mem_ctx = talloc_new(cli);
 167         struct dom_sid *sid;
 168         unsigned i;
 169 
 170         sid = dom_sid_parse_talloc(mem_ctx, sid_str);
 171         if (sid == NULL) {
 172                 talloc_free(mem_ctx);
 173                 return NT_STATUS_INVALID_SID;
 174         }
 175 
 176         status = smblsa_sid_privileges(cli, sid, mem_ctx, &rights);
 177         if (!NT_STATUS_IS_OK(status)) {
 178                 talloc_free(mem_ctx);
 179                 return status;
 180         }
 181 
 182         for (i=0;i<rights.count;i++) {
 183                 if (strcmp(rights.names[i].string, privilege) == 0) {
 184                         talloc_free(mem_ctx);
 185                         return NT_STATUS_OK;
 186                 }
 187         }
 188 
 189         talloc_free(mem_ctx);
 190         return NT_STATUS_NOT_FOUND;
 191 }
 192 
 193 
 194 /*
 195   lookup a SID, returning its name
 196 */
 197 NTSTATUS smblsa_lookup_sid(struct smbcli_state *cli, 
     /* [<][>][^][v][top][bottom][index][help] */
 198                            const char *sid_str,
 199                            TALLOC_CTX *mem_ctx,
 200                            const char **name)
 201 {
 202         struct lsa_LookupSids r;
 203         struct lsa_TransNameArray names;
 204         struct lsa_SidArray sids;
 205         struct lsa_RefDomainList *domains = NULL;
 206         uint32_t count = 1;
 207         NTSTATUS status;
 208         struct dom_sid *sid;
 209         TALLOC_CTX *mem_ctx2 = talloc_new(mem_ctx);
 210 
 211         status = smblsa_connect(cli);
 212         if (!NT_STATUS_IS_OK(status)) {
 213                 return status;
 214         }
 215 
 216         sid = dom_sid_parse_talloc(mem_ctx2, sid_str);
 217         if (sid == NULL) {
 218                 return NT_STATUS_INVALID_SID;
 219         }
 220 
 221         names.count = 0;
 222         names.names = NULL;
 223 
 224         sids.num_sids = 1;
 225         sids.sids = talloc(mem_ctx2, struct lsa_SidPtr);
 226         sids.sids[0].sid = sid;
 227 
 228         r.in.handle = &cli->lsa->handle;
 229         r.in.sids = &sids;
 230         r.in.names = &names;
 231         r.in.level = 1;
 232         r.in.count = &count;
 233         r.out.count = &count;
 234         r.out.names = &names;
 235         r.out.domains = &domains;
 236 
 237         status = dcerpc_lsa_LookupSids(cli->lsa->pipe, mem_ctx2, &r);
 238         if (!NT_STATUS_IS_OK(status)) {
 239                 talloc_free(mem_ctx2);
 240                 return status;
 241         }
 242         if (names.count != 1) {
 243                 talloc_free(mem_ctx2);
 244                 return NT_STATUS_UNSUCCESSFUL;
 245         }
 246 
 247         (*name) = talloc_asprintf(mem_ctx, "%s\\%s", 
 248                                   domains->domains[0].name.string,
 249                                   names.names[0].name.string);
 250 
 251         talloc_free(mem_ctx2);
 252 
 253         return NT_STATUS_OK;    
 254 }
 255 
 256 /*
 257   lookup a name, returning its sid
 258 */
 259 NTSTATUS smblsa_lookup_name(struct smbcli_state *cli, 
     /* [<][>][^][v][top][bottom][index][help] */
 260                             const char *name,
 261                             TALLOC_CTX *mem_ctx,
 262                             const char **sid_str)
 263 {
 264         struct lsa_LookupNames r;
 265         struct lsa_TransSidArray sids;
 266         struct lsa_String names;
 267         struct lsa_RefDomainList *domains = NULL;
 268         uint32_t count = 1;
 269         NTSTATUS status;
 270         struct dom_sid *sid;
 271         TALLOC_CTX *mem_ctx2 = talloc_new(mem_ctx);
 272         uint32_t rid;
 273 
 274         status = smblsa_connect(cli);
 275         if (!NT_STATUS_IS_OK(status)) {
 276                 return status;
 277         }
 278 
 279         sids.count = 0;
 280         sids.sids = NULL;
 281 
 282         names.string = name;
 283 
 284         r.in.handle = &cli->lsa->handle;
 285         r.in.num_names = 1;
 286         r.in.names = &names;
 287         r.in.sids = &sids;
 288         r.in.level = 1;
 289         r.in.count = &count;
 290         r.out.count = &count;
 291         r.out.sids = &sids;
 292         r.out.domains = &domains;
 293 
 294         status = dcerpc_lsa_LookupNames(cli->lsa->pipe, mem_ctx2, &r);
 295         if (!NT_STATUS_IS_OK(status)) {
 296                 talloc_free(mem_ctx2);
 297                 return status;
 298         }
 299         if (sids.count != 1) {
 300                 talloc_free(mem_ctx2);
 301                 return NT_STATUS_UNSUCCESSFUL;
 302         }
 303 
 304         sid = domains->domains[0].sid;
 305         rid = sids.sids[0].rid;
 306         
 307         (*sid_str) = talloc_asprintf(mem_ctx, "%s-%u", 
 308                                      dom_sid_string(mem_ctx2, sid), rid);
 309 
 310         talloc_free(mem_ctx2);
 311 
 312         return NT_STATUS_OK;    
 313 }
 314 
 315 
 316 /*
 317   add a set of privileges to the given sid
 318 */
 319 NTSTATUS smblsa_sid_add_privileges(struct smbcli_state *cli, struct dom_sid *sid, 
     /* [<][>][^][v][top][bottom][index][help] */
 320                                    TALLOC_CTX *mem_ctx,
 321                                    struct lsa_RightSet *rights)
 322 {
 323         NTSTATUS status;
 324         struct lsa_AddAccountRights r;
 325 
 326         status = smblsa_connect(cli);
 327         if (!NT_STATUS_IS_OK(status)) {
 328                 return status;
 329         }
 330 
 331         r.in.handle = &cli->lsa->handle;
 332         r.in.sid = sid;
 333         r.in.rights = rights;
 334 
 335         return dcerpc_lsa_AddAccountRights(cli->lsa->pipe, mem_ctx, &r);
 336 }
 337 
 338 /*
 339   remove a set of privileges from the given sid
 340 */
 341 NTSTATUS smblsa_sid_del_privileges(struct smbcli_state *cli, struct dom_sid *sid, 
     /* [<][>][^][v][top][bottom][index][help] */
 342                                    TALLOC_CTX *mem_ctx,
 343                                    struct lsa_RightSet *rights)
 344 {
 345         NTSTATUS status;
 346         struct lsa_RemoveAccountRights r;
 347 
 348         status = smblsa_connect(cli);
 349         if (!NT_STATUS_IS_OK(status)) {
 350                 return status;
 351         }
 352 
 353         r.in.handle = &cli->lsa->handle;
 354         r.in.sid = sid;
 355         r.in.remove_all = 0;
 356         r.in.rights = rights;
 357 
 358         return dcerpc_lsa_RemoveAccountRights(cli->lsa->pipe, mem_ctx, &r);
 359 }

/* [<][>][^][v][top][bottom][index][help] */