A geometry shader sits between the vertex shader and the fragment (or pixel) shader in the rendering pipeline. It will take the processed vertices from the vertex shader and create a new set of vertices to be processed by the fragment shader.
More specifically, a geometry shader will take a primitive as an input. This primitive can be a point, a line or a triangle. From that input, the geometry shader can generate additional primitives or simply modify the input primitive.
Most commonly, a geometry shader will be used to add complexity to a given input data structure. Like creating a quad from a point (in case of billboard for a particle), or creating additional lines for two single points (in case of interpolating a curve) or even adding complexity to a mesh, by creating additional triangles that make up a more complex mesh than the original input.