r23779: Change from v2 or later to v3 or later.
[nivanova/samba-autobuild/.git] / source3 / nsswitch / winbindd_sid.c
index 13b2cd05550133fb7a162fdef6e7f3157df428e8..84a7e76e78fe8077f98ef5690bff4eb1092fbad8 100644 (file)
@@ -7,7 +7,7 @@
    
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
    
    This program is distributed in the hope that it will be useful,
@@ -103,7 +103,8 @@ void winbindd_lookupname(struct winbindd_cli_state *state)
                  name_domain, lp_winbind_separator(), name_user));
 
        winbindd_lookupname_async(state->mem_ctx, name_domain, name_user,
-                                 lookupname_recv, state);
+                                 lookupname_recv, WINBINDD_LOOKUPNAME, 
+                                 state);
 }
 
 static void lookupname_recv(void *private_data, BOOL success,
@@ -183,6 +184,40 @@ static void sid2uid_recv(void *private_data, BOOL success, uid_t uid)
        request_ok(state);
 }
 
+static void sid2uid_lookupsid_recv( void *private_data, BOOL success, 
+                                   const char *domain_name, 
+                                   const char *name, 
+                                   enum lsa_SidType type)
+{
+       struct winbindd_cli_state *state =
+               talloc_get_type_abort(private_data, struct winbindd_cli_state);
+       DOM_SID sid;
+
+       if (!success) {
+               DEBUG(5, ("sid2uid_lookupsid_recv Could not convert get sid type for %s\n",
+                         state->request.data.sid));
+               request_error(state);
+               return;
+       }
+
+       if ( (type!=SID_NAME_USER) && (type!=SID_NAME_COMPUTER) ) {
+               DEBUG(5,("sid2uid_lookupsid_recv: Sid %s is not a user or a computer.\n", 
+                        state->request.data.sid));
+               request_error(state);
+               return;         
+       }
+
+       if (!string_to_sid(&sid, state->request.data.sid)) {
+               DEBUG(1, ("sid2uid_lookupsid_recv: Could not get convert sid %s from string\n",
+                         state->request.data.sid));
+               request_error(state);
+               return;
+       }
+       
+       /* always use the async interface (may block) */
+       winbindd_sid2uid_async(state->mem_ctx, &sid, sid2uid_recv, state);
+}
+
 void winbindd_sid_to_uid(struct winbindd_cli_state *state)
 {
        DOM_SID sid;
@@ -200,8 +235,11 @@ void winbindd_sid_to_uid(struct winbindd_cli_state *state)
                return;
        }
 
-       /* always use the async interface (may block) */
-       winbindd_sid2uid_async(state->mem_ctx, &sid, sid2uid_recv, state);
+       /* Validate the SID as a user.  Hopefully this will hit cache.
+          Needed to prevent DoS by exhausting the uid allocation
+          range from random SIDs. */
+
+       winbindd_lookupsid_async( state->mem_ctx, &sid, sid2uid_lookupsid_recv, state );
 }
 
 /* Convert a sid to a gid.  We assume we only have one rid attached to the
@@ -223,6 +261,43 @@ static void sid2gid_recv(void *private_data, BOOL success, gid_t gid)
        request_ok(state);
 }
 
+static void sid2gid_lookupsid_recv( void *private_data, BOOL success, 
+                                   const char *domain_name, 
+                                   const char *name, 
+                                   enum lsa_SidType type)
+{
+       struct winbindd_cli_state *state =
+               talloc_get_type_abort(private_data, struct winbindd_cli_state);
+       DOM_SID sid;
+
+       if (!success) {
+               DEBUG(5, ("sid2gid_lookupsid_recv: Could not get sid type for %s\n",
+                         state->request.data.sid));
+               request_error(state);
+               return;
+       }
+
+       if ( (type!=SID_NAME_DOM_GRP) &&
+            (type!=SID_NAME_ALIAS) && 
+            (type!=SID_NAME_WKN_GRP) ) 
+       {
+               DEBUG(5,("sid2gid_lookupsid_recv: Sid %s is not a group.\n", 
+                        state->request.data.sid));
+               request_error(state);
+               return;         
+       }
+
+       if (!string_to_sid(&sid, state->request.data.sid)) {
+               DEBUG(1, ("sid2gid_lookupsid_recv: Could not get convert sid %s from string\n",
+                         state->request.data.sid));
+               request_error(state);
+               return;
+       }
+       
+       /* always use the async interface (may block) */
+       winbindd_sid2gid_async(state->mem_ctx, &sid, sid2gid_recv, state);
+}
+
 void winbindd_sid_to_gid(struct winbindd_cli_state *state)
 {
        DOM_SID sid;
@@ -240,8 +315,11 @@ void winbindd_sid_to_gid(struct winbindd_cli_state *state)
                return;
        }
 
-       /* always use the async interface (may block) */
-       winbindd_sid2gid_async(state->mem_ctx, &sid, sid2gid_recv, state);
+       /* Validate the SID as a group.  Hopefully this will hit cache.
+          Needed to prevent DoS by exhausting the uid allocation
+          range from random SIDs. */
+
+       winbindd_lookupsid_async( state->mem_ctx, &sid, sid2gid_lookupsid_recv, state );        
 }
 
 static void sids2xids_recv(void *private_data, BOOL success, void *data, int len)